Separator tysięcy JavaScript / format ciągu [duplikat]


99

Czy w JavaScript jest jakaś funkcja do formatowania liczb i ciągów?

Szukam sposobu na separator tysięcy dla ciągu lub liczb ... (jak String.Format w C #)



Myślę, że znajdziesz tam to, czego potrzebujesz :) stackoverflow.com/questions/610406/…
Jad

How to print a number with commas as thousands separators in JavaScript: stackoverflow.com/questions/2901102/…
Adrien Be

Odpowiedzi:


168

Aktualizacja (7 lat później)

Odniesienie cytowane w oryginalnej odpowiedzi poniżej było błędne. Tam jest wbudowany w funkcji dla tego, co jest dokładnie to, co Kaiser sugeruje poniżej:toLocaleString

Więc możesz zrobić:

(1234567.89).toLocaleString('en')              // for numeric input
parseFloat("1234567.89").toLocaleString('en')  // for string input

Funkcja zaimplementowana poniżej również działa, ale po prostu nie jest konieczna.

(Pomyślałem, że może będę miał szczęście i okaże się, że było to konieczne w 2010 r., Ale nie. Zgodnie z tym bardziej wiarygodnym odniesieniem toLocaleString jest częścią standardu od 3. wydania ECMAScript [1999], co moim zdaniem oznacza to byłby obsługiwany już w IE 5.5.)


Oryginalna odpowiedź

Zgodnie z tym odniesieniem nie ma wbudowanej funkcji dodawania przecinków do liczby. Ale ta strona zawiera przykład, jak samodzielnie ją zakodować:

function addCommas(nStr) {
    nStr += '';
    var x = nStr.split('.');
    var x1 = x[0];
    var x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
            x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}

Edycja: Aby przejść w drugą stronę (przekonwertować ciąg z przecinkami na liczbę), możesz zrobić coś takiego:

parseFloat("1,234,567.89".replace(/,/g,''))

Naprawdę naprawdę to doceniam // Ale jak mogę zamienić ten ciąg (przecinkami) na liczbę?
LostLord

ta funkcja nie działa dla liczb większych niż 100 000
DevZer0

1
@ DevZer0 nie, nie ma
Tallboy

działa z czystym javascript + pojedynczym wyrażeniem regularnym zamień stackoverflow.com/a/44324879/681830
Val

4
użyj (1234567).toLocaleString().replace(/,/g," ",)dla przestrzeni między tysiącami
Fanky

122

Jeśli chodzi o lokalizację separatorów tysięcy, ograniczników i separatorów dziesiętnych, wykonaj następujące czynności:

// --> numObj.toLocaleString( [locales [, options] ] )
parseInt( number ).toLocaleString();

Istnieje kilka opcji, których możesz użyć (a nawet ustawienia regionalne z rezerwami):

number = 123456.7089;

result  = parseInt( number ).toLocaleString() + "<br>";
result += number.toLocaleString( 'de-DE' ) + "<br>";
result += number.toLocaleString( 'ar-EG' ) + "<br>";
result += number.toLocaleString( 'ja-JP', { 
  style           : 'currency',
  currency        : 'JPY',
  currencyDisplay : 'symbol',
  useGrouping     : true
} ) + "<br>";
result += number.toLocaleString( [ 'jav', 'en' ], { 
  localeMatcher            : 'lookup',
  style                    : 'decimal',
  minimumIntegerDigits     : 2,
  minimumFractionDigits    : 2,
  maximumFractionDigits    : 3,
  minimumSignificantDigits : 2,
  maximumSignificantDigits : 3
} ) + "<br>";

var el = document.getElementById( 'result' );
el.innerHTML = result;
<div id="result"></div>

Szczegóły na stronie informacyjnej MDN .

Edycja: Komentator @ Lubię Serenę dodaje:

Aby obsługiwać przeglądarki z ustawieniami regionalnymi innymi niż angielski, w których nadal chcemy formatować w języku angielskim, użyj value.toLocaleString('en'). Działa również dla zmiennoprzecinkowych.


To nie obejmuje liczb zmiennoprzecinkowych. Możesz zmienić parseInt na parseFloat, ale jeśli yourInt = "100,12" (przecinek jako separator dziesiętny) to się nie powiedzie. Można to naprawić za pomocą zamiany (",", ".") .. ale ponownie zakończy się niepowodzeniem przy "1.000,12". Więc ... Czasami MUSISZ wynaleźć koło na nowo. stackoverflow.com/a/2901298/1028304
neiker

1
To byłoby bardziej odpowiednie:Number(yourNumberOrString).toLocaleString()
Jonathan

2
Aby obsługiwać przeglądarki z ustawieniami regionalnymi innymi niż angielski, w których nadal chcemy formatować w języku angielskim, użyj value.toLocaleString('en'). Działa również dla zmiennoprzecinkowych.
Klaas van Aarsen

1
@ Serhiog.Lazin Co dokładnie nie działa w Safari (i na jakim systemie operacyjnym iw której wersji)?
kaiser

1
FYI, dla Indii jak format numeru 7,77,77,777, zastosowanievalue.toLocaleString('en-IN')
Makesh

37

Zaktualizowano przy użyciu obsługi wstecznej zgodnie ze zmianami ECMAScript2018.
Aby uzyskać zgodność wsteczną, przewiń w dół, aby zobaczyć oryginalne rozwiązanie.

Można użyć wyrażenia regularnego - jest to szczególnie przydatne w przypadku dużych liczb przechowywanych jako łańcuchy.

const format = num => 
    String(num).replace(/(?<!\..*)(\d)(?=(?:\d{3})+(?:\.|$))/g, '$1,')

;[
    format(100),                           // "100"
    format(1000),                          // "1,000"
    format(1e10),                          // "10,000,000,000"  
    format(1000.001001),                   // "1,000.001001"
    format('100000000000000.001001001001') // "100,000,000,000,000.001001001001
]
    .forEach(n => console.log(n))

»Pełne wyjaśnienie wyrażenia regularnego (regex101.com) schemat przepływu


Ta oryginalna odpowiedź może nie być wymagana, ale można jej użyć w celu zapewnienia zgodności wstecznej.

Próbując poradzić sobie z tym za pomocą pojedynczego wyrażenia regularnego (bez wywołania zwrotnego), moja obecna umiejętność zawodzi mnie z powodu braku negatywnego spojrzenia wstecz w Javascript ... nie mniej jednak, oto kolejna zwięzła alternatywa, która działa w większości przypadków - uwzględnianie dowolnego przecinka dziesiętnego ignorując dopasowania, w których indeks dopasowania występuje po indeksie kropki.

const format = num => {
    const n = String(num),
          p = n.indexOf('.')
    return n.replace(
        /\d(?=(?:\d{3})+(?:\.|$))/g,
        (m, i) => p < 0 || i < p ? `${m},` : m
    )
}

;[
    format(100),                           // "100"
    format(1000),                          // "1,000"
    format(1e10),                          // "10,000,000,000"  
    format(1000.001001),                   // "1,000.001001"
    format('100000000000000.001001001001') // "100,000,000,000,000.001001001001
]
    .forEach(n => console.log(n))

»Pełne wyjaśnienie wyrażenia regularnego (regex101.com)

schemat przepływu


Czy ten diagram składni został utworzony w witrynie regex101.com?
Gerold Broser

co się dzieje z liczbami dziesiętnymi?
Emiliano,

Otrzymuję komunikat „Nieprawidłowe wyrażenie regularne: nieprawidłowa nazwa specyfikatora grupy”. W React Native 0.59 robienie tego, ale to naprawdę nie powinno wpływać na RegEx.
Joshua Pinter

@JoshuaPinter Będzie to użycie spojrzenia wstecz, które w chwili pisania nie jest jeszcze obsługiwane na wszystkich platformach. Zgaduję, że odnosisz się konkretnie do iOS - ponieważ Safari też nie działa dla mnie. Na razie najlepiej będzie trzymać się wersji kompatybilnej wstecz. Chciałem tylko sprawdzić swoją odpowiedź na przyszłość. caniuse.com/#search=lookbehind
Emisariusz

1
@Emissary Dzięki za wskazówkę. Tak, działa na React Native 0.59 / Android, który używa stosunkowo starszej wersji JavaScriptCore (JSC). Spróbuję ponownie po aktualizacji do React Native 0.60+, która obejmuje aktualizację JSC.
Joshua Pinter

11

Jest fajna wtyczka numeru jQuery: https://github.com/teamdf/jquery-number

Pozwala na zmianę dowolnej liczby w formacie, który lubisz, z opcjami dla cyfr dziesiętnych i znaków separatora dla dziesiętnych i tysięcy:

$.number(12345.4556, 2);          // -> 12,345.46
$.number(12345.4556, 3, ',', ' ') // -> 12 345,456

Możesz go używać bezpośrednio w polach wejściowych, co jest przyjemniejsze, używając tych samych opcji, co powyżej:

$("input").number(true, 2);

Lub możesz zastosować do całego zestawu elementów DOM za pomocą selektora:

$('span.number').number(true, 2);

best solution imho
Michał

Nie sądzę, dodając nowe wymagania dotyczące plików z prawie 800 wierszami, to jak zabić mrówkę granatem
Emiliano

6

Używam tego:

function numberWithCommas(number) {
    return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

źródło: link


'123452343267.0505'.replace(/\B(?=(\d{3})+(?!\d))/g, ","); "123,452,343,267.0,505"- zauważ, że ostatni przecinek po przecinku.
hippietrail

5
// thousand separates a digit-only string using commas
// by element:  onkeyup = "ThousandSeparate(this)"
// by ID:       onkeyup = "ThousandSeparate('txt1','lbl1')"
function ThousandSeparate()
{
    if (arguments.length == 1)
    {
        var V = arguments[0].value;
        V = V.replace(/,/g,'');
        var R = new RegExp('(-?[0-9]+)([0-9]{3})'); 
        while(R.test(V))
        {
            V = V.replace(R, '$1,$2');
        }
        arguments[0].value = V;
    }
    else  if ( arguments.length == 2)
    {
        var V = document.getElementById(arguments[0]).value;
        var R = new RegExp('(-?[0-9]+)([0-9]{3})'); 
        while(R.test(V))
        {
            V = V.replace(R, '$1,$2');
        }
        document.getElementById(arguments[1]).innerHTML = V;
    }
    else return false;
}   


3

Możesz użyć javascript. poniżej jest kod, będzie on tylko acceptnumeryczny i jedendot

tutaj jest javascript

<script >

            function FormatCurrency(ctrl) {
                //Check if arrow keys are pressed - we want to allow navigation around textbox using arrow keys
                if (event.keyCode == 37 || event.keyCode == 38 || event.keyCode == 39 || event.keyCode == 40) {
                    return;
                }

                var val = ctrl.value;

                val = val.replace(/,/g, "")
                ctrl.value = "";
                val += '';
                x = val.split('.');
                x1 = x[0];
                x2 = x.length > 1 ? '.' + x[1] : '';

                var rgx = /(\d+)(\d{3})/;

                while (rgx.test(x1)) {
                    x1 = x1.replace(rgx, '$1' + ',' + '$2');
                }

                ctrl.value = x1 + x2;
            }

            function CheckNumeric() {
                return event.keyCode >= 48 && event.keyCode <= 57 || event.keyCode == 46;
            }

  </script>

HTML

<input type="text" onkeypress="return CheckNumeric()" onkeyup="FormatCurrency(this)" />

DEMO JSFIDDLE



2
number = 123456.7089;
result = parseInt( number ).toLocaleString() + "<br>";
result = number.toLocaleString( 'pt-BR' ) + "<br>";

var el = document.getElementById( 'result' );
el.innerHTML = result;
<div id="result"></div>

6
Czy możesz dodać również opis, aby OP i inne osoby mogły zrozumieć, w jaki sposób ten kod faktycznie rozwiązuje problem. Dzięki
Punit Gajjar

spróbuj z nomberem od 1000 do 9999
Emiliano

1

Wszystko, co musisz zrobić, to po prostu naprawdę to :

123000.9123.toLocaleString()
//result will be "123,000.912"

Niestety zależy to od Twojej platformy. Niektóre mają znak, toLocaleString()który nie dodaje przecinków lub nie ma innych funkcji w standardzie. Łatwo jest sprawdzić toLocaleStringobecność, ale nie sprawdzić jej zgodności.
hippietrail

spróbuj z liczbą od 1000 do 9999
Emiliano

0

Połączenie rozwiązań do reagowania

  let converter = Intl.NumberFormat();
  let salary =  monthlySalary.replace(/,/g,'')
  console.log(converter.format(salary))

  this.setState({
    monthlySalary: converter.format(salary)
  })
}

handleOnChangeMonthlySalary(1000)```

0

Możesz użyć ngx-format-field. Jest to dyrektywa służąca do formatowania wartości wejściowej, która pojawi się w widoku. Nie będzie manipulować wartością wejściową, która zostanie zapisana w zapleczu. Zobacz link tutaj !

Przykład:

component.html:

<input type="text" formControlName="currency" [appFormatFields]="CURRENCY"
(change)="onChangeCurrency()">

component.ts

onChangeCurrency() {
this.currency.patchValue(this.currency.value);
}

Aby zobaczyć demo: tutaj !


0

Możesz użyć następującej funkcji:

function format(number, decimals = 2, decimalSeparator = '.', thousandsSeparator = ',') {
  const roundedNumber = number.toFixed(decimals);
  let integerPart = '',
    fractionalPart = '';
  if (decimals == 0) {
    integerPart = roundedNumber;
    decimalSeparator = '';
  } else {
    let numberParts = roundedNumber.split('.');
    integerPart = numberParts[0];
    fractionalPart = numberParts[1];
  }
  integerPart = integerPart.replace(/(\d)(?=(\d{3})+(?!\d))/g, `$1${thousandsSeparator}`);
  return `${integerPart}${decimalSeparator}${fractionalPart}`;
}

// Use Example

let min = 1556454.0001;
let max = 15556982.9999;

console.time('number format');
for (let i = 0; i < 15; i++) {
  let randomNumber = Math.random() * (max - min) + min;
  let formated = format(randomNumber, 4, ',', '.'); // formated number

  console.log('number: ', randomNumber, '; formated: ', formated);
}
console.timeEnd('number format');


Nie czyń tego tak zagmatwanym. po prostu użyj toLocaleString (). Więcej informacji w developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Sajad Saderi

@sajadsaderi Używam również znajomego toLocaleString (), ale ta funkcja nie daje mi dużej elastyczności, więc nie muszę mieć do czynienia ze skrótami regionalnymi i ktoś inny mógłby jej użyć, ponieważ definicja tej funkcji jest identyczna z number_format () funkcja php.
jin_maxtor

-1

Nie podobała mi się żadna z odpowiedzi tutaj, więc stworzyłem funkcję, która działała dla mnie. Chcę tylko udostępnić na wypadek, gdyby ktoś inny uznał to za przydatne.

function getFormattedCurrency(num) {
    num = num.toFixed(2)
    var cents = (num - Math.floor(num)).toFixed(2);
    return Math.floor(num).toLocaleString() + '.' + cents.split('.')[1];
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.