Come stampare un numero con virgole come migliaia di separatori in JavaScript


1784

Sto cercando di stampare un numero intero in JavaScript con virgole come migliaia di separatori. Ad esempio, voglio mostrare il numero 1234567 come "1.234.567". Come potrei fare per fare questo?

Ecco come lo sto facendo:

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

Esiste un modo più semplice o più elegante per farlo? Sarebbe bello se funziona anche con i float, ma non è necessario. Non è necessario essere specifici delle impostazioni internazionali per decidere tra punti e virgole.


156
Numero (x) .toLocaleString ()
Boffin

@Boffin questo non funziona per il numero del tipo di input (a causa delle virgole) - nella risposta accettata possiamo sostituire la virgola al punto e il numero del tipo di input funzionerà
Vitaly Zdanevich

48
Vale la pena notare che Number.prototype.toLocaleString ancora non funziona in Safari, nel 2016 . Invece di formattare effettivamente il numero, lo restituisce e non viene generato alcun errore. Avere il più grande facepalm oggi a causa di questo ... #goodworkApple
aendrew

Tuttavia, sembra funzionare in iOS Safari.
Tim

toLocaleString è incoerente e non deve essere utilizzato. Ad esempio - su Firefox questo restituirà 1.234 ma su IE questo aggiungerà decimali: 1.234,00
Bort

Risposte:


2837

Ho usato l'idea della risposta di Kerry, ma l'ho semplificata poiché stavo solo cercando qualcosa di semplice per il mio scopo specifico. Ecco cosa ho fatto:

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


Regex utilizza 2 asserzioni lookahead:

  • uno positivo per cercare qualsiasi punto nella stringa che ha un multiplo di 3 cifre consecutive dopo di essa,
  • un'asserzione negativa per assicurarsi che quel punto abbia esattamente solo un multiplo di 3 cifre. L'espressione di sostituzione inserisce una virgola lì.

Ad esempio, se lo passi 123456789.01, l'asserzione positiva corrisponderà a ogni punto a sinistra del 7 (poiché 789è un multiplo di 3 cifre, 678è un multiplo di 3 cifre 567, ecc.). L'asserzione negativa verifica che il multiplo di 3 cifre non contenga cifre successive. 789ha un punto dopo, quindi è esattamente un multiplo di 3 cifre, quindi una virgola va lì. 678è un multiplo di 3 cifre ma ha un 9dopo, quindi quelle 3 cifre fanno parte di un gruppo di 4 e una virgola non va lì. Allo stesso modo per 567. 456789è composto da 6 cifre, ovvero un multiplo di 3, quindi una virgola precede. 345678è un multiplo di 3, ma ha un 9dopo, quindi nessuna virgola va lì. E così via. Il\B impedisce alla regex di inserire una virgola all'inizio della stringa.

@ neu-rah ha menzionato che questa funzione aggiunge virgole in punti indesiderati se ci sono più di 3 cifre dopo il punto decimale. Se questo è un problema, puoi usare questa funzione:

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

@ tjcrowder ha sottolineato che ora che JavaScript ha un aspetto ( informazioni di supporto ), può essere risolto nell'espressione regolare stessa:

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

(?<!\.\d*)è un aspetto negativo che dice che la partita non può essere preceduta da un .seguito da zero o più cifre. L'aspetto negativo è più veloce della soluzione splite join( confronto ), almeno in V8.


21
Molto bello, ha notato che ha problemi con numeri che hanno più di 3 posizioni dopo il punto decimale.
Eric Petroelje,

60
try numberWithCommas (12345.6789) -> "12.345.6.789" non mi piace
neu-rah,

4
Non funziona bene con le frazioni, non vorremmo avere le virgole dopo il punto decimale
Mugen,

30
Piccolo miglioramento risolto dopo "." problema '123456789.01234'.replace (/ \ B (? = (? = \ d * \.) (\ d {3}) + (?! \ d)) / g,' _ ')
Dmitrij Golubev

8
@DmitrijGolubev Non funziona per numeri interi. Forse forzare il punto decimale sarebbe la soluzione.
Vlad

1810

Sono sorpreso che nessuno abbia menzionato Number.prototype.toLocaleString . È implementato in JavaScript 1.5 (introdotto nel 1999), quindi è sostanzialmente supportato da tutti i principali browser.

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

Funziona anche in Node.js a partire da v0.12 tramite l'inclusione di Intl

Basta prestare attenzione che questa funzione restituisce una stringa, non un numero.

Se vuoi qualcosa di diverso, Numeral.js potrebbe essere interessante.


17
@csigrist Punti positivi, ma non è così male come sembra. La velocità dipende dal browser. In FF o Opera funziona bene. Faccio schifo in Chrome però. Per quanto riguarda gli zeri: var number = 123456.000; number.toLocaleString('en-US', {minimumFractionDigits: 2}); "123,456.00"quelle opzioni non funzionano in FF o Safari però.
uKolka,

22
La differenza di prestazioni può essere o meno un problema, a seconda del contesto. Se utilizzato per una tabella gigante di 1000 risultati, sarà più importante, ma se utilizzato solo per un singolo valore, la differenza è trascurabile. Ma il vantaggio è che è a livello locale, quindi qualcuno in Europa vedrebbe 34.523.453.345 o 34 523 453.345 . Ciò sarebbe più importante in un sito con visitatori provenienti da molti paesi.
T Nguyen,

6
Eccezionale. Finalmente una risposta con funzione nativa. E per di più, questo viene visualizzato correttamente in diversi paesi con diversi separatori (nella Repubblica Ceca scriviamo X XXX XXX,YYY).
Tomáš Zato - Ripristina Monica il

22
Aggiornamento per googler: toLocaleStringfunziona in Node.js a partire da v0.12 tramite l' inclusione di Intl .
srobinson,

8
@MSC dovresti provare parseInt("1234567", 10).toLocaleString('en-US', {minimumFractionDigits: 2})o new Number("1234567").toLocaleString('en-US', {minimumFractionDigits: 2})invece. Non funziona perché lo usi su una stringa, non su un numero.
uKolka,

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

⚠ Ricorda che JavaScript ha un valore intero massimo di 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"


NumberFormat ( Safari non supportato):

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

Da quello che ho controllato (almeno Firefox) sono entrambi più o meno gli stessi per quanto riguarda le prestazioni.


6
NumberFormat non è supportato su Safari, per chiunque vi stia implementando.
marcovega,

6
toLocaleString non è supportato su Safari
Deepak Banka,

3
Il supporto per i browser è sempre menzionato nella parte inferiore di ogni pagina MDN, a cui ho collegato.
vsync,

5
toLocaleStringopere di base su Safari, opzioni no
Dandavis

3
la toLocaleStringsoluzione dovrebbe probabilmente includere anche toLocaleString("en")le impostazioni internazionali desiderate, quindi , poiché il modello inglese utilizza le virgole. Tuttavia, se toLocaleString()in Francia non viene eseguito l'indicatore delle impostazioni locali, verranno generati periodi anziché virgole perché è ciò che viene utilizzato per separare migliaia localmente.
Mike 'Pomax' Kamermans,

112

Suggerisco di usare il number_format () di phpjs.org

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

AGGIORNAMENTO 13/02/14

Le persone hanno riferito che questo non funziona come previsto, quindi ho fatto un JS Fiddle che include test automatizzati.

Aggiornamento 26/11/2017

Ecco quel violino come Stack Snippet con output leggermente modificato:

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


Non che l'ho segnato, ma credo che la gente lo abbia fatto perché non funziona. Allo stato attuale trovo che anche alcuni dei tuoi test non funzionino.
Andrew S,

3
@Andrew S - Solo 1 persona lo ha contrassegnato. Funziona, l'ho usato molte volte nel mio codice. Inoltre non è il mio codice (né i miei test), ho fatto riferimento al sito da cui proviene, che è un sito ben noto. Forse ne hanno una versione aggiornata) poiché il codice che stai visualizzando ha 3 anni.
Kerry Jones,

13
@ernix - L'operatore ha chiesto JavaScript, quella risposta che ho dato è JavaScript. Questa è un'interpretazione JavaScript di una funzione PHP.
Kerry Jones,

2
@ernix: funziona esattamente come previsto nell'esempio fornito dall'OP. Ho messo un violino in modo che tu possa vedere.
Kerry Jones,

4
@ernix - Okay, ma il punto è che fa esattamente quello che l'OP ha richiesto. Proviene da un altro sito (non gestito da me, e l'ho già detto in precedenza) e quando gli fornisce le variabili appropriate, funziona esattamente come indicato. Se ritieni che si tratti di un bug, contatta phpjs.org o vedi se hanno una versione aggiornata.
Kerry Jones,

75

Questa è una variazione della risposta di @mikez302, ma modificata per supportare i numeri con i decimali (secondo il feedback di @ neu-rah quel numero ConCommas (12345.6789) -> "12.345.6.789" invece di "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

Cosa fa ciò che la mia risposta non fa? Il regex sembra leggermente diverso ma sembra che dovrebbe fare la stessa cosa.
Elias Zamaria,

8
è più corto :)
Tutankhamen,

4
Questo è elegante Esattamente quello che stavo cercando.
tradizionale

4
Da blog.tompawlak.org/number-currency-formatting-javascript ? Problema noto: formatNumber (0.123456) = 0.123.456 L'assenza di lookbehind in JS rende difficile risolverlo con un'elegante regex.
Vlad

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

53

Usando l'espressione regolare

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

Utilizzo di 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 ()

Utilizzo di 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 QUI

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

Prestazione

Prestazione http://jsben.ch/sifRd


Questo non funziona se si digita in modo dinamico. Se gli dai un valore, funziona, ma se dai un valore costantemente in modo dinamico, le virgole vengono aggiunte nel posto sbagliato.
Edgar Quintero,

Ho aggiornato la demo sotto la mia risposta. Quando si inserisce un valore dinamico in una casella di testo. prova prova @EdgarQuintero
Ngô Quang

39

Intl.NumberFormat

Funzione JS nativa. Supportato da IE11, Edge, l'ultimo Safari, Chrome, Firefox, Opera, Safari su iOS e Chrome su Android.

var number = 3500;

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

La mia risposta è stata aggiornata in risposta ai tuoi commenti. Grazie!
Dustin Sun,

35

Grazie a tutti per le loro risposte. Ho costruito alcune delle risposte per creare una soluzione più "unica per tutti".

Il primo frammento di aggiunge una funzione che imita PHP 'il number_format()al prototipo numero. Se sto formattando un numero, di solito voglio posizioni decimali, quindi la funzione accetta il numero di posizioni decimali da mostrare. Alcuni paesi utilizzano virgole come decimali e decimali come separatore delle migliaia, quindi la funzione consente di impostare questi separatori.

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

Lo useresti come segue:

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

Ho scoperto che spesso avevo bisogno di recuperare il numero per le operazioni matematiche, ma parseFloat converte da 5.000 a 5, semplicemente prendendo la prima sequenza di valori interi. Quindi ho creato la mia funzione di conversione float e l'ho aggiunta al prototipo String.

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

Ora puoi usare entrambe le funzioni come segue:

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
Molto bello, ho preso in prestito il primo metodo;) Ma non produce un risultato corretto quando si desidera utilizzare un formato europeo e il numero è frazionario. La riga 5 dovrebbe essere:var parts = this.toFixed(decimals).toString().split('.');
vbwx

Hai ragione! toFixed () cambia la virgola in un punto e quindi '.' dovrebbe essere usato al posto di var dec_point. Grazie per la segnalazione.
Nessuno l'

puoi creare un modulo npm per questo?
amorevole

3
@ J.Money Il .toString non è necessario, toFixed restituisce già una stringa.
Ariel,

Non so perché tu abbia menzionato PHP qui, o dato una funzione prototipica che esiste
vsync

27

Sono abbastanza impressionato dal numero di risposte che questa domanda ha avuto. Mi piace la risposta di uKolka :

n.toLocaleString()

Ma sfortunatamente, in alcuni locali come lo spagnolo, non funziona (IMHO) come previsto per numeri inferiori a 10.000:

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

1000e non 1.000.

Vedere toLocaleString non funziona con numeri inferiori a 10000 in tutti i browser per sapere perché.

Quindi ho dovuto usare la risposta di Elias Zamaria scegliendo il giusto carattere separatore delle migliaia:

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

Questo funziona bene come one-liner per entrambi i locali che usano ,o .come separatore delle migliaia e inizia a lavorare da 1.000 in tutti i casi.

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

Fornisce 1.000un contesto locale spagnolo.

Se vuoi avere il controllo assoluto sul modo in cui un numero viene formattato, puoi anche provare quanto segue:

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)

1,234.57.

Questo non ha bisogno di un'espressione regolare. Funziona regolando il numero sulla quantità desiderata di decimali contoFixed , quindi dividendolo attorno al punto decimale .se ce n'è uno. Il lato sinistro viene quindi trasformato in una matrice di cifre che è invertita. Quindi un separatore di migliaia viene aggiunto ogni tre cifre dall'inizio e il risultato viene nuovamente invertito. Il risultato finale è l'unione delle due parti. Il segno del numero di input viene rimosso conMath.abs prima quindi, se necessario, nuovamente.

Non è un liner ma non molto più lungo e facilmente trasformabile in una funzione. Le variabili sono state aggiunte per maggiore chiarezza, ma possono essere sostituite dai valori desiderati se conosciute in anticipo. Puoi usare le espressioni che usano toLocaleStringcome un modo per scoprire i caratteri giusti per il punto decimale e il separatore delle migliaia per la locale corrente (tieni presente che quelli richiedono un Javascript più moderno).


23

Penso che questa sia l'espressione regolare più breve che lo fa:

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

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

L'ho controllato su alcuni numeri e ha funzionato.


funziona bene solo se non si dispone di un numero float con più di 3 numeri dopo il separatore in questo caso un punto. Altrimenti aggiunge anche una virgola. "1234567890.1234567890" .replace (/ \ B (? = (\ D {3}) + \ b) / g, ",") Non funzionerebbe ad esempio. Restituisce "1.234.567.890.1.234.567.890"
Marcio,

1
Funziona bene anche per la valuta! Basta arrotondare le cifre prima di aggiungere le virgole.
Kyle Chadha,

1
Aggiunge, dopo il punto decimale: 12.3456 ".replace (/ \ B (? = (\ D {3}) + \ b) / g,", ") == 12.3.456
Shree Tiwari

21

Number.prototype.toLocaleString()sarebbe stato fantastico se fosse stato fornito in modo nativo da tutti i browser (Safari) .

Ho controllato tutte le altre risposte ma nessuno sembrava averlo riempito. Ecco un poc verso quello, che in realtà è una combinazione delle prime due risposte; se toLocaleStringfunziona lo utilizza, in caso contrario utilizza una funzione personalizzata.

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
Tenere presente che il polyfill funziona solo con numeri che hanno al massimo 3 decimali. Ad esempio: 0.12345verrà emesso 0.12,345. Una buona implementazione per questo può essere trovata nel underscore.string
Andy,

hai ragione, mettendo una value > 1000condizione if risolve quel caso, tuttavia questo era un poc e ovviamente versioni migliori testate possono essere trovate altrove, grazie per aver sottolineato.
Sinan,

1
Non è sufficiente value > 1000, perché sarebbe lo stesso per qualsiasi numero e più di 3 decimali. es . 1000.12345ritorni 1,000.12,345. La tua risposta è ottima e sulla buona strada, ma non completa. Stavo solo cercando di evidenziare altre persone che potrebbero inciampare nella tua risposta e semplicemente copiarla / incollarla senza testare con dati di input diversi.
Andy

1
va bene, questo aveva bisogno di un'altra modifica :) Sono d'accordo, ma ora almeno dovrebbe funzionare nella maggior parte dei casi.
Sinan

18

Il separatore delle migliaia può essere inserito in modo internazionale utilizzando l' Intloggetto del browser :

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

Vedere l'articolo di MDN su NumberFormat per ulteriori informazioni, è possibile specificare il comportamento della locale o l'impostazione predefinita dell'utente. Questo è un po 'più sicuro perché rispetta le differenze locali; molti paesi usano i punti per separare le cifre mentre una virgola indica i decimali.

Intl.NumberFormat non è ancora disponibile in tutti i browser, ma funziona negli ultimi Chrome, Opera e IE. La prossima versione di Firefox dovrebbe supportarla. Webkit non sembra avere una linea temporale per l'implementazione.


2
Anche se sarebbe fantastico se potessimo usare una semplice funzione integrata, ha un'implementazione del browser terribile. Ad esempio, IE 8-10 e tutto Safari non supporta questo
Blaine Kasten,

@BlaineKasten c'è un polyfill completamente compatibile per i browser più vecchi disponibile qui: github.com/andyearnshaw/Intl.js è enorme, ma funziona.
Mahn,

1
Disponibile tramite un CDN pollyfill (restituisce solo ciò che è necessario in base all'utente user): cdn.polyfill.io/v2/polyfill.min.js?features=Intl
Kevin

Problemi con la formattazione di numeri grandi con toLocaleString, funzionava perfettamente (con polyfill)
ask_io

18

È possibile utilizzare questa procedura per formattare la valuta che necessita.

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

Per maggiori informazioni puoi accedere a questo link.

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


Questa è la risposta nativa corretta, portatile. Vorrei poter votare più di una volta.
Jared Smith,

14

se hai a che fare con valori di valuta e formattazioni molto, potrebbe valere la pena aggiungere piccoli account.js che gestiscono molti casi limite e localizzazione:

// 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
Il collegamento non funziona più. Ma sembra simile a questo: openexchangerates.github.io/accounting.js
ush189

13

Il codice seguente usa la scansione dei caratteri, quindi non c'è regex.

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] : ''); 
}

Mostra prestazioni promettenti: http://jsperf.com/number-formatting-with-commas/5

2015.4.26: Correzione minore per risolvere il problema quando num <0. Vedi https://jsfiddle.net/runsun/p5tqqvs3/


questo non funziona con commafy(-123456)esso-,123,456
wrossmck

Questo è fantastico! Grazie per aver messo insieme jsperf
fregante,

Questo frammento è un mostro assoluto, fuori esegue tutto.
NiCk Newman,

13

Ecco una semplice funzione che inserisce virgole per migliaia di separatori. Utilizza le funzioni di array anziché un 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('');
};

Collegamento CodeSandbox con esempi: https://codesandbox.io/s/p38k63w0vq


1
Ciao .. Questo esempio è fantastico. Ma inserirà virgole anche per la parte decimale. solo una modifica: funzione 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 (''); indice var = -3; while (array.length + index> 0) {array.splice (index, 0, ','); // Diminuisce di 4 poiché abbiamo appena aggiunto un'altra unità all'array. indice - = 4; } return array.join ('') + decimalPart; };
Aki143S,

Grazie Signore. Questo è esattamente ciò di cui avevo bisogno.
Amir Hossein Ahmadi,

11

Utilizzare questo codice per gestire il formato valuta per l'India. Il codice paese può essere modificato per gestire la valuta di un altro paese.

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

// Use it.

formatter.format(amount);

produzione:

3,50,256.95

Mentre questo codice può rispondere alla domanda, fornire un contesto aggiuntivo riguardo a come e / o perché risolve il problema migliorerebbe il valore a lungo termine della risposta. Leggi questo .
Shanteshwar Inde,

@ShanteshwarInde aggiungerò ulteriore contesto per migliorare la risposta certa
Bathri Nathan

11

Puoi anche usare il costruttore Intl.NumberFormat . Ecco come puoi farlo.

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

questo nodo non funzionante js. Non sta dando risposta in formato indiano
Suraj Dalvi,

7

Ho scritto questo prima di imbattermi in questo post. Nessuna regex e puoi effettivamente capire il codice.

$(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
Ho aggiunto s.toString () all'inizio della funzione in modo che possa accettare anche numeri, non solo stringhe. Questa è la mia risposta preferita perché è leggibile, concisa e non ha nessuno dei bug che sembrano avere le risposte regex.
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(".");
}

EDIT: la funzione funziona solo con un numero positivo. per esempio:

var number = -123123231232;
formatNumber(number)

Uscita: "123.123.231.232"

Ma per rispondere alla domanda sopra il toLocaleString()metodo risolve solo il problema.

var number = 123123231232;
    number.toLocaleString()

Uscita: "123.123.231.232"

Cheer!


1
Mentre questo codice può rispondere alla domanda, fornire un contesto aggiuntivo riguardo a come e / o perché risolve il problema migliorerebbe il valore a lungo termine della risposta.
Paperino

1
Bel copione, ma non funziona con numeri negativi.
Ralph David Abernathy,

7

La mia risposta è l'unica risposta che sostituisce completamente jQuery con un'alternativa molto più sensata:

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

Questa soluzione non solo aggiunge le virgole, ma si arrotonda anche al penny più vicino nel caso in cui si inserisca un importo come se $(1000.9999)si ottengano $ 1.001,00. Inoltre, il valore inserito può essere tranquillamente un numero o una stringa; non importa.

Se hai a che fare con i soldi, ma non vuoi che venga visualizzato un segno di dollaro in anticipo sull'importo, puoi anche aggiungere questa funzione, che utilizza la funzione precedente ma rimuove $:

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

Se stai non si tratta di soldi, e hanno diversi requisiti di formattazione decimali, ecco un più versatile funzione di:

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

Oh, a proposito, il fatto che questo codice non funzioni in alcune vecchie versioni di Internet Explorer è completamente intenzionale. Cerco di interrompere IE ogni volta che riesco a catturarlo senza supportare gli standard moderni.

Ricorda che elogi eccessivi, nella sezione commenti, sono considerati fuori tema. Invece, mi riempi di voti positivi.


1
Il numero (n) .toLocaleString () sembra la risposta migliore ma probabilmente vorrai usare qualcosa come il nuovo formato Intl.NumberFormat ('en-US'). (N) piuttosto che togliere i segni del dollaro e i decimali se tutti i l'utente desidera sia virgole nel loro numero.
bmacnaughton,

@bmacnaughton: è un buon punto quando non hai a che fare con i soldi. Tuttavia, se hai a che fare con il denaro e semplicemente "non vuoi il segno del dollaro principale", Number (1000.50) .toLocaleString () produce "1,000,5", che rimuove lo zero insignificante che viene normalmente mantenuto quando si visualizzano i valori di denaro. Buon commento però: tutti dovrebbero sapere cosa hai detto.
Lonnie Best

6

Per me, la risposta migliore è usare toLocaleString come hanno detto alcuni membri. Se vuoi includere il simbolo '$' aggiungi solo languaje e digita le opzioni. Ecco un esempio per formattare un numero in Pesos messicani

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

scorciatoia

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

5

Vorrei provare a migliorare la risposta di uKolka e forse aiutare gli altri a risparmiare un po 'di tempo.

Usa 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>

Dovresti andare con Number.prototype.toLocaleString () solo se la compatibilità del suo browser non è un problema.


questo mi ha ispirato a installare npm
numal

5

Un modo alternativo, che supporta decimali, diversi separatori e negativi.

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

Alcune correzioni di @Jignesh Sanghani, non dimenticare di votare il suo commento.


Perfetto per me, ho appena aggiunto una nuova riga per rimuovere la formattazione prima dell'elaborazione.
Dennis Heiden,

2
fn.substr(0, i)sostituire con n.substr(0, i)e anche number.toFixed(dp).split('.')[1]sostituire con parseFloat(number).toFixed(dp).split('.')[1]. perché quando uso direttamente mi dà un errore. aggiorna il tuo codice
Jignesh Sanghani,

imperfetto. il numero cresce. una chiamata di esempio sarebbe stata grandiosa!
mmm

il passaggio da ceil a floor ha risolto il problema, ma non è sicuro di quali altri problemi sorgeranno.
mmm

1
Prova Math.floor (-75.1);)
mmm

4

Penso che questa funzione si occuperà di tutte le questioni relative a questo problema.

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

Solo per futuri googler (o non necessariamente "googler"):

Tutte le soluzioni sopra menzionate sono meravigliose, tuttavia, RegExp potrebbe essere terribilmente brutto da usare in una situazione del genere.

Quindi, sì, potresti usare alcune delle opzioni proposte o persino scrivere qualcosa di primitivo ma utile come:

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

Il regexp usato qui è abbastanza semplice e il ciclo andrà esattamente il numero di volte necessario per completare il lavoro.

E potresti ottimizzarlo molto meglio, codice "DRYify" e così via.

Ancora,

(-1234567.0987).toLocaleString();

(nella maggior parte dei casi) sarebbe una scelta molto migliore.

Il punto non è nella velocità di esecuzione o nella compatibilità tra browser.

Nelle situazioni in cui desideri mostrare il numero risultante all'utente, il metodo .toLocaleString () ti dà la superpotenza di parlare la stessa lingua con l'utente del tuo sito Web o della tua app (qualunque sia la sua lingua).

Questo metodo secondo la documentazione ECMAScript è stato introdotto nel 1999 e credo che la ragione di ciò sia stata la speranza che Internet ad un certo punto collegherà le persone in tutto il mondo, quindi sono stati necessari alcuni strumenti di "internalizzazione".

Oggi Internet ci collega tutti, quindi è importante ricordare che il mondo è un modo molto più complesso che possiamo immaginare e che (/ quasi) tutti noi siamo qui , su Internet.

Ovviamente, considerando la diversità delle persone, è impossibile garantire la perfetta UX per tutti perché parliamo lingue diverse, valutiamo cose diverse, ecc. E proprio per questo, è ancora più importante cercare di localizzare le cose il più possibile .

Quindi, considerando che ci sono alcuni standard particolari per la rappresentazione di data, ora, numeri, ecc. E che abbiamo uno strumento per visualizzare quelle cose nel formato preferito dall'utente finale, non è così raro e quasi irresponsabile non utilizzare quello strumento (soprattutto nelle situazioni in cui vogliamo visualizzare questi dati all'utente)?

Per me, usare RegExp invece di .toLocaleString () in una situazione del genere sembra un po 'come creare un'app orologio con JavaScript e codificarla in modo tale da visualizzare solo l'ora di Praga (che sarebbe abbastanza inutile per persone che non vivono a Praga) anche se il comportamento predefinito di

new Date();

è di restituire i dati secondo l'orologio dell'utente finale.


perché hai scritto la funzione con const e =>?
OG Sean,

@OGSean Lo faccio sempre poiché è il modo più conveniente di dichiarare variabili e funzioni. Inoltre, penso che aiuta a mantenere il codice più pulito e più breve.
Igor Bykov,

4

La mia " vera " soluzione solo per le espressioni regolari per chi ama le battute one-line

Vedi quei giocatori entusiasti sopra? Forse puoi giocarci a golf. Ecco il mio colpo.

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

Utilizza un THIN SPACE (U + 2009) per un separatore di migliaia, come il Sistema Internazionale di Unità ha detto di fare nell'ottava edizione (2006) della loro pubblicazione " Brochure SI: Il Sistema Internazionale di Unità (SI) " (Vedi §5.3 .4.). La nona edizione (2019) suggerisce di utilizzare uno spazio per esso (vedere §5.4.4.). Puoi usare quello che vuoi, inclusa una virgola.


Vedere.

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


Come funziona?

Per una parte intera

.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " I ")
  • .replace(……, " I ") Metti "io"
    • /……/g a ciascuno di
      • \B l'intervallo tra due cifre adiacenti
        • (?=……)LOOKAHEAD POSITIVO la cui parte giusta è
          • (\d{3})+ uno o più blocchi di tre cifre
          • \b seguito da una non cifra, come ad esempio un punto, la fine della stringa, eccetera,
        • (?<!……)LOOKBEHIND NEGATIVO esclusi quelli la cui parte sinistra
          • \.\d+ è un punto seguito da cifre ("ha un separatore decimale").

Per una parte decimale

.replace(/(?<=\.(\d{3})+)\B/g, " F ")
  • .replace(……, " F ") Metti "F"
    • /……/g a ciascuno di
      • \B l'intervallo tra due cifre adiacenti
        • (?<=……)LOOKBEHIND POSITIVO la cui parte sinistra è
          • \. un separatore decimale
          • (\d{3})+ seguito da uno o più blocchi di tre cifre.

Classi di carattere e confini

\d

Corrisponde a qualsiasi cifra (numero arabo). Equivalente a [0-9].

Per esempio,

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

\b

Corrisponde a un limite di parole . Questa è la posizione in cui un carattere di parola non è seguito o preceduto da un altro carattere di parola, come tra una lettera e uno spazio. Si noti che un limite di parole corrispondenti non è incluso nella corrispondenza. In altre parole, la lunghezza del limite di una parola corrispondente è zero.

Esempi:

  • /\bm/corrisponde a min moon;
  • /oo\b/non corrisponde a ooin moon, perché ooè seguito da nquale è un carattere di parola;
  • /oon\b/corrisponde a oonin moon, poiché oonè la fine della stringa, quindi non seguita da un carattere parola;
  • /\w\b\w/ non corrisponderà mai a nulla, perché un carattere parola non può mai essere seguito da un carattere non-parola e un carattere-parola.

\B

Corrisponde a un limite non di parole . Questa è una posizione in cui il carattere precedente e successivo sono dello stesso tipo: o entrambi devono essere parole o entrambi devono essere non parole. Come tra due lettere o tra due spazi. L'inizio e la fine di una stringa sono considerati non parole. Come il limite di parole corrispondenti, anche il limite di non parole corrispondenti non è incluso nella corrispondenza.

Per esempio,

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

Compatibilità del browser


3

Ho aggiunto tofixed alla soluzione di Aki143S . Questa soluzione utilizza punti per migliaia di separatori e virgola per la precisione.

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(''); 
};

Esempi;

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

3

Molte buone risposte già. Eccone un altro, solo per divertimento:

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] : "");
}

Qualche esempio:

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

questo non funziona con format(-123456)esso-,123,456
wrossmck

1
Risolto (anche se esiste probabilmente un modo più elegante per farlo senza controllare ogni volta il segno). In ogni caso, l'aggiornamento fa funzionare questo con numeri negativi.
Wayne,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.