Frage So drucken Sie eine Zahl mit Kommas als Tausendertrennzeichen in JavaScript


Ich versuche, eine ganze Zahl zu drucken JavaScript mit Kommas als Tausendertrennzeichen. Zum Beispiel möchte ich die Nummer 1234567 als "1,234,567" anzeigen. Wie würde ich das machen?

Hier ist, wie ich es mache:

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 einen einfacheren oder eleganteren Weg? Es wäre schön, wenn es auch mit Floats funktioniert, aber das ist nicht nötig. Es muss nicht länderspezifisch sein, um zwischen Punkten und Kommas zu unterscheiden.


1165
2018-05-24 23:42


Ursprung


Antworten:


Ich benutzte die Idee aus Kerrys Antwort, vereinfachte sie aber, da ich nur nach etwas Einfachem für meinen speziellen Zweck suchte. Hier ist, was ich getan habe:

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

Das ist alles, was Sie wirklich wissen müssen.

@Neils Bom fragte, wie die Regex funktioniert. Meine Erklärung ist irgendwie lang. Es passt nicht in die Kommentare und ich weiß nicht, wo ich es sonst noch hinstellen soll, also mache ich es hier. Wenn jemand andere Vorschläge hat, wo Sie ihn hinstellen können, lassen Sie es mich bitte wissen.

Die Regex verwendet zwei Lookahead-Assertions: einen positiven, der nach einem beliebigen Punkt in der Zeichenfolge sucht, der mehrere 3 Ziffern in Folge hinter ihm hat, und eine negative Assertion, um sicherzustellen, dass dieser Punkt nur genau ein Vielfaches von 3 Ziffern aufweist. Der Ersatzausdruck setzt ein Komma dort.

Zum Beispiel, wenn Sie es "123456789.01" übergeben, wird die positive Behauptung jeder Stelle auf der linken Seite der 7 übereinstimmen (da "789" ist ein Vielfaches von 3 Ziffern, "678" ist ein Vielfaches von 3 Ziffern, "567", etc.). Die negative Assertion überprüft, dass das Vielfache von 3 Ziffern keine Ziffern dahinter hat. "789" hat einen Punkt danach, also ist es genau ein Vielfaches von 3 Ziffern, also geht ein Komma dorthin. "678" ist ein Vielfaches von 3 Ziffern, aber es hat eine "9" hinter ihm, so dass diese 3 Ziffern Teil einer Gruppe von 4 sind, und ein Komma geht nicht dorthin. Ähnlich für "567". "456789" ist 6 Ziffern, was ein Vielfaches von 3 ist, also geht vorher ein Komma. "345678" ist ein Vielfaches von 3, hat aber eine "9", also kein Komma. Und so weiter. Das "\ B" verhindert, dass die Regex ein Komma am Anfang der Zeichenfolge setzt.

@ neu-rah hat erwähnt, dass diese Funktion Kommas an unerwünschten Stellen hinzufügt, wenn mehr als 3 Nachkommastellen vorhanden sind. Wenn dies ein Problem ist, können Sie diese Funktion verwenden:

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

2061
2018-05-25 00:40



Ich bin überrascht, dass niemand erwähnt hat Number.prototype.toLocaleString. Es wurde in JavaScript 1.5 (das 1999 eingeführt wurde) implementiert, so dass es im Grunde von allen gängigen Browsern unterstützt wird.

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

Es funktioniert auch in Node.js ab v0.12 über die Einbindung von Intl

Wenn du etwas anderes willst, Ziffer.js könnte interessant sein.


1046
2017-07-15 21:01



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

 Beachten Sie, dass Javascript eine hat maximale Ganzzahl Wert von 9007199254740991


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"


Zahlenformat (Safari nicht unterstützt):

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

Von dem, was ich überprüft habe (zumindest Firefox), sind beide hinsichtlich der Leistung mehr oder weniger gleich.


177
2017-08-22 08:52



Ich schlage vor, phpjs.org 's zu benutzen Zahlenformat()

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

Leute haben berichtet, dass dies nicht wie erwartet funktioniert, also habe ich eine JS Geige Dazu gehören automatisierte Tests.

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;
}


86
2018-05-24 23:47



Dies ist eine Variation der @ mikez302-Antwort, aber modifiziert, um Zahlen mit Dezimalzahlen zu unterstützen (pro @ neu-rahs Feedback, dass numberWithCommas (12345.6789) -> "12.345.6.789" statt "12.345.6789"

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

65
2018-06-05 15:03



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

54
2017-08-19 06:47



Danke an alle für ihre Antworten. Ich habe einige der Antworten erstellt, um eine Lösung zu schaffen, die für alle passt.

Das erste Snippet fügt eine Funktion hinzu, die nachahmt PHPist es number_format() zum Prototyp der Nummer. Wenn ich eine Zahl formatiere, möchte ich normalerweise Dezimalstellen, so dass die Funktion die Anzahl der angezeigten Dezimalstellen einnimmt. Einige Länder verwenden Kommas als Dezimaltrennzeichen und Dezimalzeichen als Tausendertrennzeichen, sodass die Funktion das Setzen dieser Trennzeichen ermöglicht.

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 fand, dass ich oft die Zahl für mathematische Operationen zurückholen musste, aber parseFloat konvertiert 5.000 zu 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

31
2017-09-18 01:50



Int.NummerFormat

Native JS-Funktion. Unterstützt von IE11, Edge, neueste Safari, Chrome, Firefox, Opera, Safari auf iOS und Chrome auf Android.

var number = 3500;

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

28
2017-10-31 23:56



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

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

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

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


22
2018-03-13 06:31