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

Sto cercando di stampare un numero intero in JavaScript con virgole come separatori di migliaia. Ad esempio, voglio mostrare il numero 1234567 come “1,234,567”. Come potrei 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; } 

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

Ho usato l’idea della risposta di Kerry, ma l’ho semplificata dal momento che stavo cercando qualcosa di semplice per il mio scopo specifico. Ecco cosa ho fatto:

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

Questo è tutto ciò che devi veramente sapere.

@Neils Bom ha chiesto come funziona la regex. La mia spiegazione è abbastanza lunga. Non andrà bene nei commenti e non so dove altro metterlo così lo sto facendo qui. Se qualcuno ha altri suggerimenti su dove metterlo, per favore fatemelo sapere.

La regex utilizza 2 asserzioni lookahead: una positiva per cercare qualsiasi punto nella stringa che ha un multiplo di 3 cifre di seguito, e un’asserzione negativa per assicurarsi che quel punto abbia esattamente un multiplo di 3 cifre. L’espressione sostitutiva 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”, eccetera.). L’asserzione negativa controlla che il multiplo di 3 cifre non abbia cifre dopo di esso. “789” ha un punto dopo di esso, quindi è esattamente un multiplo di 3 cifre, quindi una virgola va lì. “678” è un multiplo di 3 cifre ma ha un “9” dopo di esso, quindi quelle 3 cifre fanno parte di un gruppo di 4, e una virgola non va lì. Allo stesso modo per “567”. “456789” è di 6 cifre, che è un multiplo di 3, quindi una virgola va prima. “345678” è un multiplo di 3, ma ha un “9” dopo di esso, quindi nessuna virgola va lì. E così via. “\ B” mantiene la regex di mettere una virgola all’inizio della stringa.

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

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

Sono sorpreso che nessuno abbia menzionato Number.prototype.toLocaleString . È implementato in JavaScript 1.5 (che è stato introdotto nel 1999), quindi è fondamentalmente supportato nei principali browser.

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

Funziona anche in Node.js a partire dalla v0.12 tramite l’inclusione di Intl

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

 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 per Firefox) sono entrambi più o meno identici per quanto riguarda le prestazioni.

Suggerisco di usare 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 segnalato che questo non funziona come previsto, quindi ho fatto un JS Fiddle che include test automatici.

Aggiornamento 26/11/2017

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

Questa è una variazione della risposta di @ mikez302, ma modificata per supportare numeri con decimali (per feedback di @ neu-rah che numeroWithCommas (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] : ""); } 
 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 

Grazie a tutti per le loro risposte. Ho risolto alcune delle risposte per creare una soluzione più “taglia unica”.

Il primo frammento aggiunge una funzione che simula il number_format() PHP number_format() sul prototipo Numero. Se sto formattando un numero, di solito voglio le posizioni decimali, quindi la funzione prende il numero di posizioni decimali da mostrare. Alcuni paesi utilizzano le virgole come decimale e decimale come separatore delle migliaia, in modo che la funzione consenta 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. Così 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 utilizzare 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 

Intl.NumberFormat

Funzione JS nativa. Supportato da IE11, Edge, 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 

Penso che questa sia l’espressione regolare più corta che lo fa:

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

Ho controllato su alcuni numeri e ha funzionato.

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

Ho controllato tutte le altre risposte ma nessuno sembrava riempirlo di polilinee. Ecco un poc verso ciò, che in realtà è una combinazione di prime due risposte; se toLocaleString funziona lo usa, se non usa 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)); 

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

  


Using Regular expression

Using toLocaleString()

Using Intl.NumberFormat()

Il separatore delle migliaia può essere inserito in un modo amichevole internazionale usando l’object Intl 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, è ansible specificare il comportamento locale o predefinito per l’utente. Questo è un po ‘più infallibile perché rispetta le differenze locali; molti paesi usano periodi 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 supportarlo. Webkit non sembra avere una tempistica per l’implementazione.

se hai a che fare con valori di valuta e formattazione molto, allora potrebbe valere la pena aggiungere tiny accounting.js che gestisce 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 

Il seguente codice usa char scan, 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?'':((Li)%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/

È ansible utilizzare questa procedura per formattare la propria valuta.

 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 è ansible accedere a questo link.

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

Ecco una semplice funzione che inserisce virgole per migliaia di separatori. Usa funzioni di array piuttosto che una RegEx.

 /** * Format a number as a string with commas separating the thousands. * @param num - The number to be formatted (eg 10000) * @return A string representing the formatted number (eg "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(''); }; 

Ho scritto questo prima di inciampare 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' ) ); }); 
  

Lasciami provare a migliorare la risposta di uKolka e magari aiutare gli altri a risparmiare un po ‘di tempo.

Utilizza Numeral.js .

 document.body.textContent = numeral(1234567).format('0,0'); 
  

For me, the best answer is using toLocaleString like some members said. If you want to include the ‘$’ symbol just add languaje and type options. Here is and example to format a number to Mexican Pesos

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

I think this function will take care of all the issues related to this problem.

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

I added tofixed to Aki143S ‘s solution. This solution uses dots for thousands separators and comma for the precision.

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

Examples;

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

I think your solution is one of the shorter ones I’ve seen for this. I don’t think there are any standard JavaScript functions to do this sort of thing, so you’re probably on your own.

I checked the CSS 3 specifications to see whether it’s possible to do this in CSS, but unless you want every digit in its own , I don’t think that’s possible.

I did find one project on Google Code that looked promising: flexible-js-formatting . I haven’t used it, but it looks pretty flexible and has unit tests using JsUnit . The developer also has a lot of posts (though old) about this topic.

Be sure to consider international users: lots of nations use a space as the separator and use the comma for separating the decimal from the integral part of the number.

Lots of good answers already. Here’s another, just for fun:

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

Some examples:

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

Here’s my try:

EDIT: Added in decimals

 function splitMille(n, separator = ',') { // Cast to string let num = (n + '') // Test for and get any decimals (the later operations won't support them) let decimals = '' if (/\./.test(num)) { // This regex grabs the decimal point as well as the decimal numbers decimals = num.replace(/^.*(\..*)$/, '$1') } // Remove decimals from the number string num = num.replace(decimals, '') // Reverse the number string through Array functions .split('').reverse().join('') // Split into groups of 1-3 characters (with optional supported character "-" for negative numbers) .match(/[0-9]{1,3}-?/g) // Add in the mille separator character and reverse back .join(separator).split('').reverse().join('') // Put the decimals back and output the formatted number return `${num}${decimals}` } let testA = splitMille(1234) let testB = splitMille(-1234) let testC = splitMille(123456.789) let testD = splitMille(9007199254740991) let testE = splitMille(1000.0001) console.log('Results!\n\tA: %s\n\tB: %s\n\tC: %s\n\tD: %s\n\tE: %s', testA, testB, testC, testD, testE) 

After not finding a modern and comprehensive solution here, I have written an arrow function (without regex) to solve the formatting problem and it allows the caller to provide number of fraction digits as well as the period and thousand separator for Europe and rest of the world.

Esempi:

 numberFormatter(1234567890.123456) => 1,234,567,890 numberFormatter(1234567890.123456, 4) => 1,234,567,890.1235 numberFormatter(1234567890.123456, 4, '.', ',') => 1.234.567.890,1235 Europe 

Here is the function written in ES6 (modern syntax):

 const numberFormatter = (number, fractionDigits = 0, thousandSeperator = ',', fractionSeperator = '.') => { if (number!==0 && !number || !Number.isFinite(number)) return number const frDigits = Number.isFinite(fractionDigits)? Math.min(Math.max(fractionDigits, 0), 7) : 0 const num = number.toFixed(frDigits).toString() const parts = num.split('.') let digits = parts[0].split('').reverse() let sign = '' if (num < 0) {sign = digits.pop()} let final = [] let pos = 0 while (digits.length > 1) { final.push(digits.shift()) pos++ if (pos % 3 === 0) {final.push(thousandSeperator)} } final.push(digits.shift()) return `${sign}${final.reverse().join('')}${frDigits > 0 ? fractionSeperator : ''}${frDigits > 0 && parts[1] ? parts[1] : ''}` } 

It has been tested for negative, bad input and NaN cases . If the input is NaN then it simply returns it.

The solution from @user1437663 is great.

Who really understands the solution is being prepared to understand complex regular expressions.

A small improvement to make it more readable:

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

The pattern starts with \B to avoid use comma at the beginning of a word. Interestingly, the pattern is returned empty because \B does not advance the “cursor” (the same applies to $ ).

O \B is followed by a less known resources but is a powerful feature from Perl’s regular expressions.

  Pattern1 (? = (Pattern2) ). 

The magic is that what is in parentheses ( Pattern2 ) is a pattern that follows the previous pattern ( Pattern1 ) but without advancing the cursor and also is not part of the pattern returned. It is a kind of future pattern. This is similar when someone looks forward but really doesn’t walk!

In this case pattern2 is

 \d{3})+(?=$) 

It means 3 digits (one or more times) followed by the end of the string ($)

Finally, Replace method changes all occurrences of the pattern found (empty string) for comma. This only happens in cases where the remaining piece is a multiple of 3 digits (such cases where future cursor reach the end of the origin).

Here is good solution with less coding…

 var y = ""; var arr = x.toString().split(""); for(var i=0; i 

An alternative way, supporting decimals, different separators and negatives.

 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.abs(Math.ceil(number)).toString() , i = n.length % 3 , f = n.substr(0, i) ; if(number < 0) f = '-' + f; for(;i 0) f += ds + number.toFixed(dp).split('.')[1] return f; } 

I’ve adapted your code to work in TextBox (Input type=”text”) so we can enter and delete digits in real time without losing cursor. It’s works also if you select range when you delete. And you can use arrows and home/end buttons freely.
Thanks for saving my time!

 //function controls number format as "1,532,162.3264321" function numberWithCommas(x) { var e = e || window.event; if (e.keyCode >= '35' && e.keyCode < = '40') return; //skip arrow-keys var selStart = x.selectionStart, selEnd = x.selectionEnd; //save cursor positions var parts = x.value.toString().split("."); var part0len = parts[0].length; //old length to check if new ',' would be added. Need for correcting new cursor position (+1 to right). //if user deleted ',' - remove previous number instead (without selection) if (x.selectionLength == 0 && (e.keyCode == 8 || e.keyCode == 46)) {//if pressed 8-backspace or 46-delete button var delPos = parts[0].search(/\d{4}/); if (delPos != -1) {//if found 4 digits in a row (',' is deleted) if (e.keyCode == 8) {//if backspace flag parts[0] = parts[0].slice(0, selStart - 1) + parts[0].slice(selEnd, parts[0].length); selEnd--; if (selStart > selEnd) selStart = selEnd; } else { parts[0] = parts[0].slice(0, selStart) + parts[0].slice(selEnd + 1, parts[0].length); selStart++; if (selEnd < selStart) selEnd = selStart; } } } var hasMinus = parts[0][0] == '-'; parts[0] = (hasMinus ? '-' : '') + parts[0].replace(/[^\d]*/g, ""); //I'd like to clear old ',' to avoid things like 1,2,3,5,634.443216 parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); //sets ',' between each 3 digits if (part0len < parts[0].length) { //move cursor to right if added new ',' selStart++; selEnd++; } else if (part0len > parts[0].length) { //..or if removed last one ',' selStart--; selEnd--; } x.value = parts.join("."); x.setSelectionRange(selStart, selEnd); //restoring cursor position } function saveSelectionLength(x) { x.selectionLength = x.selectionEnd - x.selectionStart; } 

To use this just added two events – onKeyUp and onKeyDown