So drucken Sie eine Zahl mit Kommas als Tausendertrennzeichen in JavaScript


1781

Ich versuche, eine Ganzzahl in JavaScript zu drucken mit Kommas als Tausendertrennzeichen . Zum Beispiel möchte ich die Nummer 1234567 als "1.234.567" anzeigen. Wie würde ich das machen?

So mache ich das:

function numberWithCommas(x) {
    x = x.toString();
    var pattern = /(-?\d+)(\d{3})/;
    while (pattern.test(x))
        x = x.replace(pattern, "$1,$2");
    return x;
}

Gibt es eine einfachere oder elegantere Möglichkeit? Es wäre schön, wenn es auch mit Schwimmern funktioniert, aber das ist nicht nötig. Es muss nicht länderspezifisch sein, um zwischen Punkten und Kommas zu entscheiden.


156
Nummer (x) .toLocaleString ()
Boffin

@Boffin dies funktioniert nicht für Eingabetypnummer (wegen Kommas) - in akzeptierter Antwort können wir Komma durch Punkt ersetzen und Eingabetypnummer wird funktionieren
Vitaly Zdanevich

48
Bemerkenswert ist, dass dies in Safari 2016 Number.prototype.toLocaleString immer noch nicht funktioniert . Anstatt die Nummer tatsächlich zu formatieren, wird sie nur zurückgegeben, ohne dass ein Fehler ausgelöst wird. Das größte Gesichtspalme heute als Ergebnis davon haben ... #goodworkApple
aendrew

Es scheint jedoch in iOS-Safari zu funktionieren.
Tim

toLocaleString ist inkonsistent und sollte nicht verwendet werden. Zum Beispiel - auf Firefox wird dies 1.234 zurückgeben, aber auf IE werden Dezimalstellen hinzugefügt: 1.234,00
Bort

Antworten:


2833

Ich habe die Idee aus Kerrys Antwort verwendet, sie aber vereinfacht, da ich nur nach etwas Einfachem für meinen speziellen Zweck gesucht habe. Folgendes habe ich getan:

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


Der Regex verwendet zwei Lookahead-Behauptungen:

  • eine positive, um nach einem Punkt in der Zeichenfolge zu suchen, der ein Vielfaches von 3 Ziffern hintereinander enthält,
  • eine negative Aussage, um sicherzustellen, dass dieser Punkt nur ein Vielfaches von 3 Ziffern hat. Der Ersetzungsausdruck setzt dort ein Komma.

Wenn Sie es beispielsweise bestehen, stimmt 123456789.01die positive Behauptung mit jedem Punkt links von der 7 überein (da 789es sich um ein Vielfaches von 3 Ziffern, 678ein Vielfaches von 3 Ziffern 567usw. handelt). Die negative Behauptung überprüft, ob das Vielfache von 3 Ziffern keine Ziffern hinter sich hat. 789hat einen Punkt danach, also ist es genau ein Vielfaches von 3 Ziffern, also geht dort ein Komma. 678ist ein Vielfaches von 3 Ziffern, aber es hat ein 9Nachher, so dass diese 3 Ziffern Teil einer Gruppe von 4 sind und ein Komma nicht dorthin geht. Ähnliches gilt für 567. 456789ist 6 Stellen, was ein Vielfaches von 3 ist, also steht davor ein Komma. 345678ist ein Vielfaches von 3, aber es hat ein 9Nachher, so dass dort kein Komma steht. Und so weiter. Das\B verhindert, dass der reguläre Ausdruck am Anfang der Zeichenfolge ein Komma setzt.

@ neu-rah erwähnte, dass diese Funktion Kommas an unerwünschten Stellen hinzufügt, wenn mehr als 3 Stellen nach dem Dezimalpunkt stehen. Wenn dies ein Problem ist, können Sie diese Funktion verwenden:

function numberWithCommas(x) {
    var parts = x.toString().split(".");
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    return parts.join(".");
}

@ tjcrowder wies darauf hin, dass JavaScript nun, da es Lookbehind ( Support-Informationen ) hat, im regulären Ausdruck selbst gelöst werden kann:

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

(?<!\.\d*)ist ein negativer Lookbehind, der besagt, dass der Übereinstimmung keine vorangestellten .null oder mehr Ziffern vorangestellt werden können . Das negative Lookbehind ist zumindest in V8 schneller als die splitund join-Lösung ( Vergleich ).


21
Sehr cool, habe bemerkt, dass es Probleme mit Zahlen gibt, die mehr als 3 Stellen nach dem Dezimalpunkt haben.
Eric Petroelje

60
try numberWithCommas (12345.6789) -> "12,345.6,789" Ich mag es nicht
neu-rah

4
Es funktioniert nicht gut mit Brüchen, wir möchten keine Kommas nach dem Dezimalpunkt haben
Mugen

30
Kleine Verbesserung, die nach '.' Problem '123456789.01234'.replace (/ \ B (? = (? = \ d * \.) (\ d {3}) + (?! \ d)) / g,' _ ')
Dmitrij Golubev

8
@DmitrijGolubev Funktioniert nicht für ganze Zahlen. Vielleicht wäre das Erzwingen des Dezimalpunkts die Lösung.
Vlad

1809

Ich bin überrascht, dass niemand Number.prototype.toLocaleString erwähnt hat . Es ist in JavaScript 1.5 (das 1999 eingeführt wurde) implementiert und wird daher grundsätzlich von allen gängigen Browsern unterstützt.

var n = 34523453.345
n.toLocaleString()
"34,523,453.345"

Es funktioniert auch in Node.js ab Version 0.12 durch Einbeziehung von Intl

Achten Sie nur darauf, dass diese Funktion eine Zeichenfolge und keine Zahl zurückgibt.

Wenn Sie etwas anderes wollen, könnte Numeral.js interessant sein.


17
@csigrist Gute Punkte, aber es ist nicht so schlecht, wie es scheint. Die Geschwindigkeit ist browserabhängig. In FF oder Opera funktioniert es gut. Ich sauge aber in Chrome. Was Nullen betrifft: var number = 123456.000; number.toLocaleString('en-US', {minimumFractionDigits: 2}); "123,456.00"Diese Optionen funktionieren jedoch nicht in FF oder Safari.
uKolka

22
Der Leistungsunterschied kann je nach Kontext ein Problem sein oder auch nicht. Wenn es für eine riesige Tabelle mit 1000 Ergebnissen verwendet wird, ist es wichtiger, aber wenn es nur für einen einzelnen Wert verwendet wird, ist der Unterschied vernachlässigbar. Der Vorteil ist jedoch, dass das Gebietsschema bekannt ist, sodass jemand in Europa 34.523.453.345 oder 34 523 453.345 sehen würde . Dies wäre auf einer Website mit Besuchern aus vielen Ländern wichtiger.
T Nguyen

6
Genial. Endlich eine Antwort mit nativer Funktion. Und außerdem wird dieser in verschiedenen Ländern mit unterschiedlichen Trennzeichen richtig angezeigt (in der Tschechischen Republik schreiben wir X XXX XXX,YYY).
Tomáš Zato - Wiedereinsetzung Monica

22
Update für Googler: Funktioniert toLocaleStringin Node.js ab Version 0.12 über die Aufnahme von Intl .
Srobinson

8
@MSC sollten Sie versuchen parseInt("1234567", 10).toLocaleString('en-US', {minimumFractionDigits: 2})oder new Number("1234567").toLocaleString('en-US', {minimumFractionDigits: 2})stattdessen. Es funktioniert nicht, weil Sie es für eine Zeichenfolge verwenden, nicht für eine Zahl.
Großbritannien Kolka

244
var number = 1234567890; // Example number to be converted

⚠ Beachten Sie, dass Javascript einen maximalen ganzzahligen Wert von 9007199254740991 hat


toLocaleString :

number.toLocaleString(); // "1,234,567,890"

// A more complex example: 
var number2 = 1234.56789; // floating point example
number2.toLocaleString(undefined, {maximumFractionDigits:2}) // "1,234.57"


NumberFormat ( Safari wird nicht unterstützt):

var nf = new Intl.NumberFormat();
nf.format(number); // "1,234,567,890"

Nach dem, was ich überprüft habe (zumindest Firefox), sind beide in Bezug auf die Leistung mehr oder weniger gleich.


6
NumberFormat wird in Safari nicht für alle unterstützt, die dort implementieren.
Marcovega

6
toLocaleString wird auch auf Safari nicht unterstützt
Deepak Banka

3
Die Browserunterstützung wird immer am Ende jeder MDN-Seite erwähnt, auf die ich verlinkt habe.
vsync

5
Grundlegende toLocaleStringArbeiten auf Safari, Optionen nicht
Dandavis

3
Die toLocaleStringLösung sollte wahrscheinlich auch das gewünschte Gebietsschema enthalten toLocaleString("en"), da das englische Muster Kommas verwendet. Wenn toLocaleString()jedoch in Frankreich ein Indikator ohne Gebietsschema ausgeführt wird, werden anstelle von Kommas Punkte angezeigt, da auf diese Weise Tausende lokal getrennt werden.
Mike 'Pomax' Kamermans

112

Ich schlage vor, das number_format () von phpjs.org zu verwenden.

function number_format(number, decimals, dec_point, thousands_sep) {
    // http://kevin.vanzonneveld.net
    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     bugfix by: Michael White (http://getsprink.com)
    // +     bugfix by: Benjamin Lupton
    // +     bugfix by: Allan Jensen (http://www.winternet.no)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +     bugfix by: Howard Yeend
    // +    revised by: Luke Smith (http://lucassmith.name)
    // +     bugfix by: Diogo Resende
    // +     bugfix by: Rival
    // +      input by: Kheang Hok Chin (http://www.distantia.ca/)
    // +   improved by: davook
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Jay Klehr
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Amir Habibi (http://www.residence-mixte.com/)
    // +     bugfix by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Drew Noakes
    // *     example 1: number_format(1234.56);
    // *     returns 1: '1,235'
    // *     example 2: number_format(1234.56, 2, ',', ' ');
    // *     returns 2: '1 234,56'
    // *     example 3: number_format(1234.5678, 2, '.', '');
    // *     returns 3: '1234.57'
    // *     example 4: number_format(67, 2, ',', '.');
    // *     returns 4: '67,00'
    // *     example 5: number_format(1000);
    // *     returns 5: '1,000'
    // *     example 6: number_format(67.311, 2);
    // *     returns 6: '67.31'
    // *     example 7: number_format(1000.55, 1);
    // *     returns 7: '1,000.6'
    // *     example 8: number_format(67000, 5, ',', '.');
    // *     returns 8: '67.000,00000'
    // *     example 9: number_format(0.9, 0);
    // *     returns 9: '1'
    // *    example 10: number_format('1.20', 2);
    // *    returns 10: '1.20'
    // *    example 11: number_format('1.20', 4);
    // *    returns 11: '1.2000'
    // *    example 12: number_format('1.2000', 3);
    // *    returns 12: '1.200'
    var n = !isFinite(+number) ? 0 : +number, 
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        toFixedFix = function (n, prec) {
            // Fix for IE parseFloat(0.55).toFixed(0) = 0;
            var k = Math.pow(10, prec);
            return Math.round(n * k) / k;
        },
        s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return s.join(dec);
}

UPDATE 13.02.14

Die Leute haben berichtet, dass dies nicht wie erwartet funktioniert, also habe ich eine JS-Geige gemacht , die automatisierte Tests enthält.

Update 26/11/2017

Hier ist diese Geige als Stack-Snippet mit leicht modifizierter Ausgabe:

function number_format(number, decimals, dec_point, thousands_sep) {
    // http://kevin.vanzonneveld.net
    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     bugfix by: Michael White (http://getsprink.com)
    // +     bugfix by: Benjamin Lupton
    // +     bugfix by: Allan Jensen (http://www.winternet.no)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +     bugfix by: Howard Yeend
    // +    revised by: Luke Smith (http://lucassmith.name)
    // +     bugfix by: Diogo Resende
    // +     bugfix by: Rival
    // +      input by: Kheang Hok Chin (http://www.distantia.ca/)
    // +   improved by: davook
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Jay Klehr
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Amir Habibi (http://www.residence-mixte.com/)
    // +     bugfix by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Drew Noakes
    // *     example 1: number_format(1234.56);
    // *     returns 1: '1,235'
    // *     example 2: number_format(1234.56, 2, ',', ' ');
    // *     returns 2: '1 234,56'
    // *     example 3: number_format(1234.5678, 2, '.', '');
    // *     returns 3: '1234.57'
    // *     example 4: number_format(67, 2, ',', '.');
    // *     returns 4: '67,00'
    // *     example 5: number_format(1000);
    // *     returns 5: '1,000'
    // *     example 6: number_format(67.311, 2);
    // *     returns 6: '67.31'
    // *     example 7: number_format(1000.55, 1);
    // *     returns 7: '1,000.6'
    // *     example 8: number_format(67000, 5, ',', '.');
    // *     returns 8: '67.000,00000'
    // *     example 9: number_format(0.9, 0);
    // *     returns 9: '1'
    // *    example 10: number_format('1.20', 2);
    // *    returns 10: '1.20'
    // *    example 11: number_format('1.20', 4);
    // *    returns 11: '1.2000'
    // *    example 12: number_format('1.2000', 3);
    // *    returns 12: '1.200'
    var n = !isFinite(+number) ? 0 : +number, 
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        toFixedFix = function (n, prec) {
            // Fix for IE parseFloat(0.55).toFixed(0) = 0;
            var k = Math.pow(10, prec);
            return Math.round(n * k) / k;
        },
        s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return s.join(dec);
}

var exampleNumber = 1;
function test(expected, number, decimals, dec_point, thousands_sep)
{
    var actual = number_format(number, decimals, dec_point, thousands_sep);
    console.log(
        'Test case ' + exampleNumber + ': ' +
        '(decimals: ' + (typeof decimals === 'undefined' ? '(default)' : decimals) +
        ', dec_point: "' + (typeof dec_point === 'undefined' ? '(default)' : dec_point) + '"' +
        ', thousands_sep: "' + (typeof thousands_sep === 'undefined' ? '(default)' : thousands_sep) + '")'
    );
    console.log('  => ' + (actual === expected ? 'Passed' : 'FAILED') + ', got "' + actual + '", expected "' + expected + '".');
    exampleNumber++;
}

test('1,235',    1234.56);
test('1 234,56', 1234.56, 2, ',', ' ');
test('1234.57',  1234.5678, 2, '.', '');
test('67,00',    67, 2, ',', '.');
test('1,000',    1000);
test('67.31',    67.311, 2);
test('1,000.6',  1000.55, 1);
test('67.000,00000', 67000, 5, ',', '.');
test('1',        0.9, 0);
test('1.20',     '1.20', 2);
test('1.2000',   '1.20', 4);
test('1.200',    '1.2000', 3);
.as-console-wrapper {
  max-height: 100% !important;
}


Nicht, dass ich es notiert hätte, aber ich glaube, die Leute haben es getan, weil es nicht funktioniert. So wie es aussieht, funktionieren sogar einige Ihrer Tests nicht.
Andrew S

3
@ Andrew S - Nur 1 Person hat es markiert. Es funktioniert, ich habe es viele Male in meinem eigenen Code verwendet. Es ist auch nicht mein Code (noch meine Tests), ich habe auf die Site verwiesen, von der es stammt, die eine bekannte Site ist. Vielleicht haben sie eine aktualisierte Version davon), da der Code, den Sie sich ansehen, 3 Jahre alt ist.
Kerry Jones

13
@ernix - Der Operator hat nach JavaScript gefragt. Die Antwort, die ich gegeben habe, ist JavaScript. Dies ist eine JavaScript-Interpretation einer PHP-Funktion.
Kerry Jones

2
@ernix - es funktioniert genau wie erwartet mit dem Beispiel, das das OP gegeben hat. Ich habe eine Geige gelegt, damit du sehen kannst.
Kerry Jones

4
@ernix - Okay, aber der Punkt ist, dass es genau das tut , was das OP verlangt hat. Es stammt von einer anderen Site (nicht von mir gepflegt, und ich habe dies bereits angegeben), und wenn es die richtigen Variablen angibt, funktioniert es genau wie angegeben. Wenn Sie glauben, dass dies ein Fehler ist, wenden Sie sich an phpjs.org oder prüfen Sie, ob eine aktualisierte Version vorliegt.
Kerry Jones

75

Dies ist eine Variation der Antwort von @ mikez302, wurde jedoch geändert, um Zahlen mit Dezimalstellen zu unterstützen (gemäß @ neu-rahs Feedback, dass numberWithCommas (12345.6789) -> "12.345,6,789" anstelle von "12.345.6789"

function numberWithCommas(n) {
    var parts=n.toString().split(".");
    return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (parts[1] ? "." + parts[1] : "");
}


67
function formatNumber (num) {
    return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}

print(formatNumber(2665));      // 2,665
print(formatNumber(102665));    // 102,665
print(formatNumber(111102665)); // 111,102,665

Was macht das, was meine Antwort nicht tut? Die Regex sieht etwas anders aus, aber es sieht so aus, als ob sie dasselbe tun sollte.
Elias Zamaria

8
es ist kürzer :)
Tutanchamun

4
Das ist elegant. Genau das, wonach ich gesucht habe.
traditionelle

4
Von blog.tompawlak.org/number-currency-formatting-javascript ? Bekanntes Problem: formatNumber (0.123456) = 0.123.456 Das Fehlen von Lookbehind in JS macht es schwierig, es mit einem eleganten regulären Ausdruck zu beheben.
Vlad

1
123456789.123456789.toString (). Ersetzen (/ (\ d) (? = (\ D {3}) + \.) / G, '$ 1,') => 123.456.789.12345679
Kenberkeley

53

Regulären Ausdruck verwenden

function toCommas(value) {
    return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(toCommas(123456789)); // 123,456,789

console.log(toCommas(1234567890)); // 1,234,567,890
console.log(toCommas(1234)); // 1,234

Verwenden von toLocaleString ()

var number = 123456.789;

// request a currency format
console.log(number.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }));
// → 123.456,79 €

// the Japanese yen doesn't use a minor unit
console.log(number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }))
// → ¥123,457

// limit to three significant digits
console.log(number.toLocaleString('en-IN', { maximumSignificantDigits: 3 }));
// → 1,23,000

ref MDN: Number.prototype.toLocaleString ()

Verwenden von Intl.NumberFormat ()

var number = 123456.789;

console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
// expected output: "123.456,79 €"

// the Japanese yen doesn't use a minor unit
console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number));
// expected output: "¥123,457"

// limit to three significant digits
console.log(new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(number));

// expected output: "1,23,000"

ref Intl.NumberFormat

DEMO HIER

<script type="text/javascript">
  // Using Regular expression
  function toCommas(value) {
    return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  }

  function commas() {
    var num1 = document.myform.number1.value;

    // Using Regular expression
    document.getElementById('result1').value = toCommas(parseInt(num1));
    // Using toLocaleString()

    document.getElementById('result2').value = parseInt(num1).toLocaleString('ja-JP', {
      style: 'currency',
      currency: 'JPY'
    });

    // Using Intl.NumberFormat()
    document.getElementById('result3').value = new Intl.NumberFormat('ja-JP', {
      style: 'currency',
      currency: 'JPY'
    }).format(num1);
  }
</script>
<FORM NAME="myform">
  <INPUT TYPE="text" NAME="number1" VALUE="123456789">
  <br>
  <INPUT TYPE="button" NAME="button" Value="=>" onClick="commas()">
  <br>Using Regular expression
  <br>
  <INPUT TYPE="text" ID="result1" NAME="result1" VALUE="">
  <br>Using toLocaleString()
  <br>
  <INPUT TYPE="text" ID="result2" NAME="result2" VALUE="">
  <br>Using Intl.NumberFormat()
  <br>
  <INPUT TYPE="text" ID="result3" NAME="result3" VALUE="">

</FORM>

Performance

Performance http://jsben.ch/sifRd


Dies funktioniert nicht, wenn Sie dynamisch tippen. Wenn Sie ihm nur einen Wert geben, funktioniert dies, aber wenn Sie einen Wert ständig dynamisch eingeben, werden die Kommas an der falschen Stelle hinzugefügt.
Edgar Quintero

Ich habe die Demo unter meiner Antwort aktualisiert. Bei Eingabe eines dynamischen Wertes in ein Textfeld. Sie testen versuchen @EdgarQuintero
Tính Ngô Quang

39

Intl.NumberFormat

Native JS-Funktion. Unterstützt von IE11, Edge, den neuesten Versionen von Safari, Chrome, Firefox, Opera, Safari für iOS und Chrome für Android.

var number = 3500;

console.log(new Intl.NumberFormat().format(number));
// → '3,500' if in US English locale

Meine Antwort wurde als Antwort auf Ihre Kommentare aktualisiert. Vielen Dank!
Dustin Sun

35

Vielen Dank an alle für ihre Antworten. Ich habe einige der Antworten zusammengestellt, um eine "Einheitslösung" zu schaffen.

Der erste Schnipsel fügt eine Funktion hinzu , dass ahmt PHP ‚s number_format()an die Nummer Prototyp. Wenn ich eine Zahl formatiere, möchte ich normalerweise Dezimalstellen, damit die Funktion die Anzahl der anzuzeigenden Dezimalstellen berücksichtigt. Einige Länder verwenden Kommas als Dezimalzahl und Dezimalstellen als Tausendertrennzeichen, sodass diese Funktion die Funktion ermöglicht, diese Trennzeichen festzulegen.

Number.prototype.numberFormat = function(decimals, dec_point, thousands_sep) {
    dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
    thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';

    var parts = this.toFixed(decimals).split('.');
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousands_sep);

    return parts.join(dec_point);
}

Sie würden dies wie folgt verwenden:

var foo = 5000;
console.log(foo.numberFormat(2)); // us format: 5,000.00
console.log(foo.numberFormat(2, ',', '.')); // european format: 5.000,00

Ich stellte fest, dass ich die Zahl für mathematische Operationen oft zurückbekommen musste, aber parseFloat konvertiert 5.000 in 5 und nimmt einfach die erste Folge von ganzzahligen Werten. Also habe ich meine eigene Float-Konvertierungsfunktion erstellt und sie dem String-Prototyp hinzugefügt.

String.prototype.getFloat = function(dec_point, thousands_sep) {
    dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
    thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';

    var parts = this.split(dec_point);
    var re = new RegExp("[" + thousands_sep + "]");
    parts[0] = parts[0].replace(re, '');

    return parseFloat(parts.join(dec_point));
}

Jetzt können Sie beide Funktionen wie folgt verwenden:

var foo = 5000;
var fooString = foo.numberFormat(2); // The string 5,000.00
var fooFloat = fooString.getFloat(); // The number 5000;

console.log((fooString.getFloat() + 1).numberFormat(2)); // The string 5,001.00

2
Sehr schön, ich habe mir die erste Methode ausgeliehen;) Aber sie liefert kein korrektes Ergebnis, wenn Sie ein europäisches Format verwenden möchten und die Zahl gebrochen ist. Zeile 5 sollte sein:var parts = this.toFixed(decimals).toString().split('.');
vbwx

Sie haben Recht! toFixed () ändert das Komma in einen Punkt und damit das '.' sollte anstelle von verwendet werden var dec_point. Vielen Dank für den Hinweis.
Keine

Kannst du dafür ein npm-Modul erstellen?
Chovy

3
@ J.Money Der .toString ist nicht erforderlich, toFixed gibt bereits einen String zurück.
Ariel

Ich weiß nicht, warum Sie hier überhaupt PHP erwähnt oder eine bereits vorhandene
vsync

27

Ich bin ziemlich beeindruckt von der Anzahl der Antworten, die diese Frage hat. Ich mag die Antwort von uKolka :

n.toLocaleString()

Leider funktioniert es in einigen Regionen wie Spanisch nicht wie erwartet (IMHO) für Zahlen unter 10.000:

Number(1000).toLocaleString('ES-es')

Gibt 1000und nicht1.000 .

Siehe toLocaleString funktioniert nicht in allen Browsern mit Zahlen unter 10000 mit , erfahren Sie, warum.

Also musste ich die Antwort von Elias Zamaria verwenden , um das richtige Tausendertrennzeichen auszuwählen :

n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))

Dieser funktioniert gut als Einzeiler für beide Gebietsschemas, die ,oder .als Tausendertrennzeichen verwenden, und beginnt in allen Fällen mit der Arbeit ab 1.000.

Number(1000).toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))

Gibt 1.000mit einem spanischen Gebietsschema Kontext.

Wenn Sie die Art und Weise, wie eine Zahl formatiert wird, absolut kontrollieren möchten, können Sie auch Folgendes versuchen:

let number   = 1234.567
let decimals = 2
let decpoint = '.' // Or Number(0.1).toLocaleString().substring(1, 2)
let thousand = ',' // Or Number(10000).toLocaleString().substring(2, 3)

let n = Math.abs(number).toFixed(decimals).split('.')
n[0] = n[0].split('').reverse().map((c, i, a) =>
  i > 0 && i < a.length && i % 3 == 0 ? c + thousand : c
).reverse().join('')
let final = (Math.sign(number) < 0 ? '-' : '') + n.join(decpoint)

console.log(final)

Gibt 1,234.57.

Dieser benötigt keinen regulären Ausdruck. Dazu wird zuerst die Zahl auf die gewünschte Anzahl von Dezimalstellen eingestellt toFixedund dann, .falls vorhanden, um den Dezimalpunkt geteilt . Die linke Seite wird dann in eine Anordnung von Ziffern umgewandelt, die umgekehrt wird. Dann wird von Anfang an alle drei Ziffern ein Tausendertrennzeichen hinzugefügt und das Ergebnis erneut umgekehrt. Das Endergebnis ist die Vereinigung der beiden Teile. Das Vorzeichen der eingegebenen Nummer wird mit entferntMath.abs zuerst und dann bei Bedarf zurückgesetzt.

Es ist kein Einzeiler, aber nicht viel länger und lässt sich leicht in eine Funktion verwandeln. Zur Verdeutlichung wurden Variablen hinzugefügt, die jedoch durch ihre gewünschten Werte ersetzt werden können, wenn dies im Voraus bekannt ist. Sie können die Ausdrücke verwenden toLocaleString, mit denen Sie die richtigen Zeichen für den Dezimalpunkt und das Tausendertrennzeichen für das aktuelle Gebietsschema ermitteln können (denken Sie daran, dass für diese ein moderneres Javascript erforderlich ist.)


23

Ich denke, dies ist der kürzeste reguläre Ausdruck, der dies tut:

/\B(?=(\d{3})+\b)/g

"123456".replace(/\B(?=(\d{3})+\b)/g, ",")

Ich habe ein paar Nummern überprüft und es hat funktioniert.


funktioniert nur gut, wenn Sie keine Gleitkommazahl mit mehr als 3 Zahlen nach dem Trennzeichen haben, in diesem Fall einen Punkt. Andernfalls wird auch ein Komma hinzugefügt. "1234567890.1234567890" .replace (/ \ B (? = (\ D {3}) + \ b) / g, ",") Dies würde beispielsweise nicht funktionieren. Rückgabe "1.234.567.890.1.234.567.890"
Marcio

1
Funktioniert aber gut für Währung! Runden Sie einfach Ihre Ziffern ab, bevor Sie Kommas hinzufügen.
Kyle Chadha

1
Nach dem Dezimalpunkt wird hinzugefügt: 12.3456 ".replace (/ \ B (? = (\ D {3}) + \ b) / g,", ") == 12.3.456
Shree Tiwari

21

Number.prototype.toLocaleString()wäre fantastisch gewesen, wenn es von allen Browsern (Safari) nativ bereitgestellt worden wäre .

Ich überprüfte alle anderen Antworten, aber niemand schien sie zu füllen. Hier ist ein Punkt dazu, der eigentlich eine Kombination der ersten beiden Antworten ist; Wenn es toLocaleStringfunktioniert, wird es verwendet, wenn es nicht funktioniert, wird eine benutzerdefinierte Funktion verwendet.

var putThousandsSeparators;

putThousandsSeparators = function(value, sep) {
  if (sep == null) {
    sep = ',';
  }
  // check if it needs formatting
  if (value.toString() === value.toLocaleString()) {
    // split decimals
    var parts = value.toString().split('.')
    // format whole numbers
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, sep);
    // put them back together
    value = parts[1] ? parts.join('.') : parts[0];
  } else {
    value = value.toLocaleString();
  }
  return value;
};

alert(putThousandsSeparators(1234567.890));


1
Beachten Sie, dass die Polyfüllung nur mit Zahlen funktioniert, die höchstens 3 Dezimalstellen haben. Zum Beispiel: 0.12345wird ausgegeben 0.12,345. Eine gute Implementierung dafür finden Sie in der underscore.string
Andy

Sie haben Recht, value > 1000wenn Sie eine if-Bedingung festlegen, die diesen Fall behebt. Dies war jedoch ein Problem, und natürlich können besser getestete Versionen an anderer Stelle gefunden werden, danke für den Hinweis.
Sinan

1
Es reicht nicht aus, es zu setzen value > 1000, da es für jede Zahl und mehr als 3 Dezimalstellen gleich wäre. zB 1000.12345kehrt zurück 1,000.12,345. Ihre Antwort ist großartig und auf dem richtigen Weg, aber einfach nicht vollständig. Ich habe nur versucht, auf andere Personen hinzuweisen, die möglicherweise über Ihre Antwort stolpern, und sie einfach zu kopieren / pasta, ohne sie mit anderen Eingabedaten zu testen.
Andy

1
Okay, das musste noch bearbeitet werden :) Ich stimme zu, aber jetzt sollte es zumindest in den meisten Fällen funktionieren.
Sinan

18

Das Tausendertrennzeichen kann international über das Browserobjekt eingefügt Intlwerden:

Intl.NumberFormat().format(1234);
// returns "1,234" if the user's locale is en_US, for example

Weitere Informationen finden Sie im MDN-Artikel zu NumberFormat . Sie können das Verhalten des Gebietsschemas oder die Standardeinstellung des Benutzers festlegen. Dies ist etwas narrensicherer, da lokale Unterschiede berücksichtigt werden. Viele Länder verwenden Punkte, um Ziffern zu trennen, während ein Komma die Dezimalstellen kennzeichnet.

Intl.NumberFormat ist noch nicht in allen Browsern verfügbar, funktioniert jedoch in den neuesten Versionen von Chrome, Opera und IE. Die nächste Version von Firefox sollte dies unterstützen. Webkit scheint keinen Zeitplan für die Implementierung zu haben.


2
Dies wäre zwar fantastisch, wenn wir eine einfache integrierte Funktion verwenden könnten, aber es hat eine schreckliche Browser-Implementierung. Zum Beispiel unterstützt IE 8-10 und alle Safari dies nicht
Blaine Kasten

@BlaineKasten Hier ist eine voll kompatible Polyfüllung für ältere Browser verfügbar: github.com/andyearnshaw/Intl.js Es ist riesig, aber es funktioniert.
Mahn

1
Verfügbar über ein pollyfill-CDN (gibt nur das zurück, was basierend auf useragent benötigt wird): cdn.polyfill.io/v2/polyfill.min.js?features=Intl
Kevin

Hatte Probleme beim Formatieren großer Zahlen mit toLocaleString, dies funktionierte hervorragend (mit Polyfill)
ask_io

18

Sie können entweder dieses Verfahren verwenden, um Ihre benötigte Währung zu formatieren.

var nf = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});
nf.format(123456.789); // ‘$123,456.79’

Für weitere Informationen können Sie auf diesen Link zugreifen.

https://www.justinmccandless.com/post/formatting-currency-in-javascript/


Dies ist die richtige, tragbare, native Antwort. Ich wünschte, ich könnte mehr als einmal abstimmen.
Jared Smith

14

Wenn Sie sich mit Währungswerten beschäftigen und viel formatieren, kann es sinnvoll sein, eine winzige Buchhaltung.js hinzuzufügen, die viele Randfälle und Lokalisierungen behandelt:

// Default usage:
accounting.formatMoney(12345678); // $12,345,678.00

// European formatting (custom symbol and separators), could also use options object as second param:
accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99

// Negative values are formatted nicely, too:
accounting.formatMoney(-500000, "£ ", 0); // £ -500,000

// Simple `format` string allows control of symbol position [%v = value, %s = symbol]:
accounting.formatMoney(5318008, { symbol: "GBP",  format: "%v %s" }); // 5,318,008.00 GBP

1
Link funktioniert nicht mehr. Aber sieht ähnlich aus wie dieser: openexchangerates.github.io/accounting.js
ush189

13

Der folgende Code verwendet den Char-Scan, daher gibt es keinen regulären Ausdruck.

function commafy( num){
  var parts = (''+(num<0?-num:num)).split("."), s=parts[0], L, i=L= s.length, o='';
  while(i--){ o = (i===0?'':((L-i)%3?'':',')) 
                  +s.charAt(i) +o }
  return (num<0?'-':'') + o + (parts[1] ? '.' + parts[1] : ''); 
}

Es zeigt vielversprechende Leistung: http://jsperf.com/number-formatting-with-commas/5

2015.4.26: Kleinere Korrektur zur Behebung des Problems, wenn num <0 ist. Siehe https://jsfiddle.net/runsun/p5tqqvs3/


das funktioniert nicht commafy(-123456)damit gibt-,123,456
wrossmck

Das ist toll! Vielen Dank für die Zusammenstellung der jsperf
fregante

Dieses Snippet ist ein absolutes Monster, das alles ausführt.
NiCk Newman

13

Hier ist eine einfache Funktion, die Kommas für tausend Trennzeichen einfügt. Es verwendet Array-Funktionen anstelle eines RegEx.

/**
 * Format a number as a string with commas separating the thousands.
 * @param num - The number to be formatted (e.g. 10000)
 * @return A string representing the formatted number (e.g. "10,000")
 */
var formatNumber = function(num) {
    var array = num.toString().split('');
    var index = -3;
    while (array.length + index > 0) {
        array.splice(index, 0, ',');
        // Decrement by 4 since we just added another unit to the array.
        index -= 4;
    }
    return array.join('');
};

CodeSandbox-Link mit Beispielen: https://codesandbox.io/s/p38k63w0vq


1
Hallo .. Dieses Beispiel ist großartig. Es werden aber auch Kommas für den Dezimalteil gesetzt. nur eine Bearbeitung: function formatNumber (num) {var decimalPart = ''; num = num.toString (); if (num.indexOf ('.')! = -1) {decimalPart = '.' + num.split ('.') [1]; num = parseInt (num.split ('.') [0]); } var array = num.toString (). split (''); var index = -3; while (array.length + index> 0) {array.splice (index, 0, ','); // Dekrementiere um 4, da wir dem Array gerade eine weitere Einheit hinzugefügt haben. Index - = 4; } return array.join ('') + decimalPart; };
Aki143S

Danke mein Herr. Genau das brauchte ich.
Amir Hossein Ahmadi

11

Verwenden Sie diesen Code, um das Währungsformat für Indien zu verarbeiten. Der Ländercode kann geändert werden, um andere Landeswährungen zu verarbeiten.

let amount =350256.95
var formatter = new Intl.NumberFormat('en-IN', {
  minimumFractionDigits: 2,
});

// Use it.

formatter.format(amount);

Ausgabe:

3,50,256.95

Während dieser Code die Frage möglicherweise beantwortet, würde die Bereitstellung eines zusätzlichen Kontexts darüber, wie und / oder warum das Problem gelöst wird, den langfristigen Wert der Antwort verbessern. Lesen Sie dies .
Shanteshwar Inde

@ ShanteshwarInde Ich werde zusätzlichen Kontext hinzufügen, um die Antwort sicher zu verbessern
Bathri Nathan

11

Sie können auch den Intl.NumberFormat- Konstruktor verwenden. Hier erfahren Sie, wie Sie dies tun können.

 resultNumber = new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(yourNumber); 

dieser nicht funktionierende Knoten js. Es gibt keine Antwort im indischen Format
Suraj Dalvi

7

Ich habe diesen geschrieben, bevor ich über diesen Beitrag gestolpert bin. Kein regulärer Ausdruck und Sie können den Code tatsächlich verstehen.

$(function(){
  
  function insertCommas(s) {

    // get stuff before the dot
    var d = s.indexOf('.');
    var s2 = d === -1 ? s : s.slice(0, d);

    // insert commas every 3 digits from the right
    for (var i = s2.length - 3; i > 0; i -= 3)
      s2 = s2.slice(0, i) + ',' + s2.slice(i);

    // append fractional part
    if (d !== -1)
      s2 += s.slice(d);

    return s2;

  }
  
  
  $('#theDudeAbides').text( insertCommas('1234567.89012' ) );
  
  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div id="theDudeAbides"></div>


1
Ich habe zu Beginn der Funktion s.toString () hinzugefügt, damit auch Zahlen akzeptiert werden können, nicht nur Zeichenfolgen. Dies ist meine bevorzugte Antwort, da sie lesbar und präzise ist und keinen der Fehler aufweist, die die Regex-Antworten zu haben scheinen.
FeFiFoFu

7
var formatNumber = function (number) {
  var splitNum;
  number = Math.abs(number);
  number = number.toFixed(2);
  splitNum = number.split('.');
  splitNum[0] = splitNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  return splitNum.join(".");
}

BEARBEITEN: Die Funktion funktioniert nur mit positiver Zahl. Zum Beispiel:

var number = -123123231232;
formatNumber(number)

Ausgabe: "123,123,231,232"

Aber um die obige Frage zu beantworten, toLocaleString()löst die Methode nur das Problem.

var number = 123123231232;
    number.toLocaleString()

Ausgabe: "123,123,231,232"

Jubeln!


1
Während dieser Code die Frage möglicherweise beantwortet, würde die Bereitstellung eines zusätzlichen Kontexts darüber, wie und / oder warum das Problem gelöst wird, den langfristigen Wert der Antwort verbessern.
Donald Duck

1
Schönes Skript, aber es funktioniert nicht mit negativen Zahlen.
Ralph David Abernathy

7

Meine Antwort ist die einzige Antwort, die jQuery vollständig durch eine viel sinnvollere Alternative ersetzt:

function $(dollarAmount)
{
    const locale = 'en-US';
    const options = { style: 'currency', currency: 'USD' };
    return Intl.NumberFormat(locale, options).format(dollarAmount);
}

Diese Lösung fügt nicht nur Kommas hinzu, sondern rundet auch auf den nächsten Cent, falls Sie einen Betrag $(1000.9999)eingeben, als würden Sie 1.001,00 USD erhalten. Darüber hinaus kann der von Ihnen eingegebene Wert sicher eine Zahl oder eine Zeichenfolge sein. es spielt keine Rolle.

Wenn Sie mit Geld zu tun haben, aber kein führendes Dollarzeichen auf dem Betrag angezeigt werden möchten, können Sie auch diese Funktion hinzufügen, die die vorherige Funktion verwendet, jedoch Folgendes entfernt $:

function no$(dollarAmount)
{
    return $(dollarAmount).replace('$','');
}

Wenn Sie nicht mit Geld zu tun haben und unterschiedliche Anforderungen an die Dezimalformatierung haben, finden Sie hier eine vielseitigere Funktion:

function addCommas(number, minDecimalPlaces = 0, maxDecimalPlaces = Math.max(3,minDecimalPlaces))
{
    const options = {};
    options.maximumFractionDigits = maxDecimalPlaces;
    options.minimumFractionDigits = minDecimalPlaces;
    return Intl.NumberFormat('en-US',options).format(number);
}

Übrigens ist die Tatsache, dass dieser Code in einer alten Version von Internet Explorer nicht funktioniert, völlig beabsichtigt. Ich versuche, den IE jederzeit zu unterbrechen, wenn ich feststellen kann, dass er keine modernen Standards unterstützt.

Bitte denken Sie daran, dass übermäßiges Lob im Kommentarbereich nicht zum Thema gehört. Duschen Sie mich stattdessen einfach mit Up-Votes.


1
Die Zahl (n) .toLocaleString () scheint die beste Antwort zu sein, aber Sie möchten wahrscheinlich so etwas wie das neue Intl.NumberFormat ('en-US'). Format (n) verwenden, anstatt Dollarzeichen und Dezimalstellen zu entfernen, wenn alle Benutzer möchte Kommas in ihrer Nummer.
Bmacnaughton

@bmacnaughton: Das ist ein guter Punkt, wenn Sie nicht mit Geld zu tun haben. Wenn Sie jedoch mit Geld zu tun haben und nur "das führende Dollarzeichen nicht wollen", erzeugt Number (1000.50) .toLocaleString () '1,000.5', wodurch die unbedeutende Null entfernt wird, die normalerweise bei der Anzeige von Geldwerten beibehalten wird. Guter Kommentar: Jeder sollte wissen, was Sie gesagt haben.
Lonnie Best

6

Für mich ist die beste Antwort die Verwendung von toLocaleString, wie einige Mitglieder sagten. Wenn Sie das Symbol '$' einfügen möchten, fügen Sie einfach Sprach- und Typoptionen hinzu. Hier ist ein Beispiel, um eine Zahl in mexikanische Pesos zu formatieren

var n = 1234567.22
alert(n.toLocaleString("es-MX",{style:"currency", currency:"MXN"}))

Abkürzung

1234567.22.toLocaleString("es-MX",{style:"currency", currency:"MXN"})

5

Lassen Sie mich versuchen zu verbessern uKolka ‚s Antwort und vielleicht anderen helfen speichern einige Zeit.

Verwenden Sie Numeral.js .

document.body.textContent = numeral(1234567).format('0,0');
<script src="//cdnjs.cloudflare.com/ajax/libs/numeral.js/1.4.5/numeral.min.js"></script>

Sie sollten Number.prototype.toLocaleString () nur verwenden, wenn die Browserkompatibilität kein Problem darstellt.


Dies inspirierte mich, npm numeral zu installieren
Steampowered

5

Ein alternativer Weg, der Dezimalstellen, verschiedene Trennzeichen und Negative unterstützt.

var number_format = function(number, decimal_pos, decimal_sep, thousand_sep) {
    var ts      = ( thousand_sep == null ? ',' : thousand_sep )
        , ds    = ( decimal_sep  == null ? '.' : decimal_sep )
        , dp    = ( decimal_pos  == null ? 2   : decimal_pos )

        , n     = Math.floor(Math.abs(number)).toString()

        , i     = n.length % 3 
        , f     = ((number < 0) ? '-' : '') + n.substr(0, i)
    ;

    for(;i<n.length;i+=3) {
        if(i!=0) f+=ts;
        f+=n.substr(i,3);
    }

    if(dp > 0) 
        f += ds + parseFloat(number).toFixed(dp).split('.')[1]

    return f;
}

Einige Korrekturen von @Jignesh Sanghani, vergessen Sie nicht, seinen Kommentar zu verbessern.


Perfekt für mich, habe gerade eine neue Zeile hinzugefügt, um die Formatierung vor der Verarbeitung zu entfernen.
Dennis Heiden

2
fn.substr(0, i)ersetzen durch n.substr(0, i)und auch number.toFixed(dp).split('.')[1]ersetzen durch parseFloat(number).toFixed(dp).split('.')[1]. denn wenn ich direkt benutze, gibt es mir einen Fehler. Bitte aktualisieren Sie Ihren Code
Jignesh Sanghani

fehlerhaft. Zahl wächst. Ein Exampel-Anruf wäre toll gewesen!
mmm

Das Umschalten der Decke auf den Boden hat das behoben, ist sich aber nicht sicher, welche anderen Probleme auftreten werden.
mmm

1
Versuchen Sie Math.floor (-75.1);)
mmm

4

Ich denke, diese Funktion wird sich um alle Probleme kümmern, die mit diesem Problem zusammenhängen.

function commaFormat(inputString) {
    inputString = inputString.toString();
    var decimalPart = "";
    if (inputString.indexOf('.') != -1) {
        //alert("decimal number");
        inputString = inputString.split(".");
        decimalPart = "." + inputString[1];
        inputString = inputString[0];
        //alert(inputString);
        //alert(decimalPart);

    }
    var outputString = "";
    var count = 0;
    for (var i = inputString.length - 1; i >= 0 && inputString.charAt(i) != '-'; i--) {
        //alert("inside for" + inputString.charAt(i) + "and count=" + count + " and outputString=" + outputString);
        if (count == 3) {
            outputString += ",";
            count = 0;
        }
        outputString += inputString.charAt(i);
        count++;
    }
    if (inputString.charAt(0) == '-') {
        outputString += "-";
    }
    //alert(outputString);
    //alert(outputString.split("").reverse().join(""));
    return outputString.split("").reverse().join("") + decimalPart;
}

4

Nur für zukünftige Googler (oder nicht unbedingt "Googler"):

Alle oben genannten Lösungen sind wunderbar, RegExp ist jedoch in einer solchen Situation möglicherweise eine schrecklich schlechte Sache.

Also, ja, Sie könnten einige der vorgeschlagenen Optionen verwenden oder sogar etwas Primitives und Nützliches schreiben, wie:

const strToNum = str => {

   //Find 1-3 digits followed by exactly 3 digits & a comma or end of string
   let regx = /(\d{1,3})(\d{3}(?:,|$))/;
   let currStr;

   do {
       currStr = (currStr || str.split(`.`)[0])
           .replace( regx, `$1,$2`)
   } while (currStr.match(regx)) //Stop when there's no match & null's returned

   return ( str.split(`.`)[1] ) ?
           currStr.concat(`.`, str.split(`.`)[1]) :
           currStr;

};

strToNum(`123`) // => 123
strToNum(`123456`) // => 123,456
strToNum(`-1234567.0987`) // => -1,234,567.0987

Der hier verwendete reguläre Ausdruck ist ziemlich einfach und die Schleife wird genau so oft ausgeführt, bis die Aufgabe erledigt ist.

Und Sie könnten es viel besser optimieren, "DRYify" -Code und so weiter.

Noch,

(-1234567.0987).toLocaleString();

(in den meisten Situationen) wäre eine weitaus bessere Wahl.

Der Punkt liegt nicht in der Ausführungsgeschwindigkeit oder in der Cross-Browser-Kompatibilität.

In Situationen, in denen Sie dem Benutzer die resultierende Nummer anzeigen möchten, können Sie mit der Methode .toLocaleString () mit dem Benutzer Ihrer Website oder App (unabhängig von seiner Sprache) dieselbe Sprache sprechen.

Diese Methode gemäß der ECMAScript-Dokumentation wurde 1999 eingeführt, und ich glaube, der Grund dafür war die Hoffnung, dass das Internet irgendwann Menschen auf der ganzen Welt verbinden wird. Daher wurden einige "Internalisierungs" -Tools benötigt.

Heutzutage verbindet das Internet uns alle. Daher ist es wichtig, sich daran zu erinnern, dass die Welt viel komplexer ist, als wir es uns vorstellen können, und dass (/ fast) wir alle hier im Internet sind.

Angesichts der Vielfalt der Menschen ist es offensichtlich unmöglich, eine perfekte UX für alle zu garantieren, da wir verschiedene Sprachen sprechen, verschiedene Dinge schätzen usw. Und genau aus diesem Grund ist es noch wichtiger, zu versuchen, die Dinge so weit wie möglich zu lokalisieren .

Wenn man bedenkt, dass es einige spezielle Standards für die Darstellung von Datum, Uhrzeit, Zahlen usw. gibt und dass wir ein Tool haben, um diese Dinge in dem vom Endbenutzer bevorzugten Format anzuzeigen, ist dies nicht so selten und fast unverantwortlich, dies nicht zu tun Verwenden Sie dieses Tool (insbesondere in Situationen, in denen wir diese Daten dem Benutzer anzeigen möchten)?

Für mich klingt die Verwendung von RegExp anstelle von .toLocaleString () in einer solchen Situation ein bisschen so, als würde man eine Uhr-App mit JavaScript erstellen und so hart codieren, dass nur die Prager Zeit angezeigt wird (was für ziemlich nutzlos wäre Menschen, die nicht in Prag leben), obwohl das Standardverhalten von

new Date();

ist es, die Daten gemäß der Uhr des Endbenutzers zurückzugeben.


Warum hast du die Funktion mit const und => geschrieben?
OG Sean

@OGSean mache ich immer, da es die bequemste Art ist, Variablen und Funktionen zu deklarieren. Ich denke auch, dass es hilft, den Code sauberer und kürzer zu halten.
Igor Bykov

4

Meine " wahre " Lösung nur für reguläre Ausdrücke für diejenigen, die Einzeiler lieben

Siehst du diese begeisterten Spieler oben? Vielleicht können Sie daraus Golf spielen. Hier ist mein Schlaganfall.

n => `${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " ").replace(/(?<=\.(\d{3})+)\B/g, " ")

Verwendet einen DÜNNEN RAUM (U + 2009) für ein Tausendertrennzeichen, wie es das Internationale Einheitensystem in der achten Ausgabe (2006) seiner Veröffentlichung „ SI-Broschüre: Das Internationale Einheitensystem (SI) (siehe §5.3 ) getan hat .4.). Die neunte Ausgabe (2019) schlägt vor, ein Leerzeichen dafür zu verwenden (siehe §5.4.4.). Sie können alles verwenden, was Sie möchten, einschließlich eines Kommas.


Sehen.

const integer_part_only = n => `${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " I ");
const fractional_part_only = n => `${n}`.replace(/(?<=\.(\d{3})+)\B/g, " F ");
const both = n => fractional_part_only(integer_part_only(n));

function demo(number) { // I’m using Chrome 74.
	console.log(`${number}
		 "${integer_part_only(number)}" (integer part only)
		 "${fractional_part_only(number)}" (fractional part only)
		 "${both(number)}" (both)
	`);
}
demo(Math.random() * 10e5);
demo(123456789.01234567);
demo(123456789);
demo(0.0123456789);


Wie funktioniert es?

Für einen ganzzahligen Teil

.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " I ")
  • .replace(……, " I ") Setze "Ich"
    • /……/g bei jedem von
      • \B das dazwischenliegende von zwei benachbarten Ziffern
        • (?=……)POSITIVE LOOKAHEAD, deren rechter Teil ist
          • (\d{3})+ ein oder mehrere dreistellige Blöcke
          • \b gefolgt von einer nichtstelligen Zahl, z. B. einem Punkt, dem Ende der Zeichenfolge usw.
        • (?<!……)NEGATIVER BLICK HINTER denen, deren linker Teil
          • \.\d+ ist ein Punkt, gefolgt von Ziffern ("hat ein Dezimaltrennzeichen").

Für einen Dezimalteil

.replace(/(?<=\.(\d{3})+)\B/g, " F ")
  • .replace(……, " F ") Setzen Sie "F"
    • /……/g bei jedem von
      • \B das dazwischenliegende von zwei benachbarten Ziffern
        • (?<=……)POSITIVER BLICK HINTER dessen linkem Teil ist
          • \. ein Dezimaltrennzeichen
          • (\d{3})+ gefolgt von einem oder mehreren dreistelligen Stücken.

Zeichenklassen und Grenzen

\d

Entspricht einer beliebigen Ziffer (arabische Ziffer). Entspricht [0-9].

Zum Beispiel,

  • /\d/oder /[0-9]/passt 2in B2 is the suite number.

\b

Entspricht einer Wortgrenze . Dies ist die Position, an der einem Wortzeichen kein anderes Wortzeichen folgt oder vorangestellt wird, z. B. zwischen einem Buchstaben und einem Leerzeichen. Beachten Sie, dass eine übereinstimmende Wortgrenze nicht in der Übereinstimmung enthalten ist. Mit anderen Worten ist die Länge einer übereinstimmenden Wortgrenze Null.

Beispiele:

  • /\bm/passt zum min moon;
  • /oo\b/stimmt nicht mit dem ooin überein moon, da oogefolgt wird, nwelches ein Wortzeichen ist;
  • /oon\b/stimmt mit dem oonin überein moon, da dies oondas Ende der Zeichenfolge ist und somit kein Wortzeichen folgt;
  • /\w\b\w/ wird niemals mit irgendetwas übereinstimmen, da einem Wortzeichen niemals sowohl ein Nichtwort- als auch ein Wortzeichen folgen kann.

\B

Entspricht einer Nicht-Wortgrenze . Dies ist eine Position, an der das vorherige und das nächste Zeichen vom gleichen Typ sind: Entweder müssen beide Wörter sein oder beide müssen Nichtwörter sein. Zum Beispiel zwischen zwei Buchstaben oder zwischen zwei Leerzeichen. Der Anfang und das Ende einer Zeichenfolge werden als Nichtwörter betrachtet. Wie die übereinstimmende Wortgrenze ist auch die übereinstimmende Nichtwortgrenze nicht in der Übereinstimmung enthalten.

Zum Beispiel,

  • /\Bon/passt onin at noon;
  • /ye\B/passt yein possibly yesterday.

Browser-Kompatibilität


3

Ich habe der Lösung von Aki143S tofixed hinzugefügt . Diese Lösung verwendet Punkte für Tausende Trennzeichen und Komma für die Genauigkeit.

function formatNumber( num, fixed ) { 
    var decimalPart;

    var array = Math.floor(num).toString().split('');
    var index = -3; 
    while ( array.length + index > 0 ) { 
        array.splice( index, 0, '.' );              
        index -= 4;
    }

    if(fixed > 0){
        decimalPart = num.toFixed(fixed).split(".")[1];
        return array.join('') + "," + decimalPart; 
    }
    return array.join(''); 
};

Beispiele;

formatNumber(17347, 0)  = 17.347
formatNumber(17347, 3)  = 17.347,000
formatNumber(1234563.4545, 3)  = 1.234.563,454

3

Viele gute Antworten schon. Hier ist noch eine, nur zum Spaß:

function format(num, fix) {
    var p = num.toFixed(fix).split(".");
    return p[0].split("").reduceRight(function(acc, num, i, orig) {
        if ("-" === num && 0 === i) {
            return num + acc;
        }
        var pos = orig.length - i - 1
        return  num + (pos && !(pos % 3) ? "," : "") + acc;
    }, "") + (p[1] ? "." + p[1] : "");
}

Einige Beispiele:

format(77.03453, 2); // "77.03"
format(78436589374); // "78,436,589,374"
format(784, 4);      // "784.0000"
format(-123456);     // "-123,456"

das funktioniert nicht format(-123456)damit gibt-,123,456
wrossmck

1
Behoben (obwohl es wahrscheinlich eine elegantere Möglichkeit gibt, dies zu tun, ohne jedes Mal nach dem Zeichen zu suchen). In jedem Fall funktioniert das Update mit negativen Zahlen.
Wayne
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.