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 #)

LostLord
źródło
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,''))
Tim Goodman
źródło
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.

kajzer
źródło
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

Emisariusz
źródło
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);
qdev
źródło
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

Abhishek Goel
źródło
'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;
}   
h.foroutan
źródło
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

Awtszs
źródło
2

PHP.js ma do tego funkcję o nazwie number_format . Jeśli znasz PHP, działa dokładnie tak samo .

istvanp
źródło
Pierwszy odsyłacz prowadzi do implementacji JS w wersji PHP. Jest przydatne.
o_nix,
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>
Ricardo
źródło
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"
Ezeewei
źródło
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)```
Chinedu Ofor
źródło
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 !

moumita kundu
źródło
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');

jin_maxtor
źródło
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];
}
Spencer Sullivan
źródło