I need to display a formatted number on a web page using JavaScript. I want to format it so that there are commas in the right places. How would I do this with a regular exp
// You might want to take decimals into account
Number.prototype.commas= function(){
var s= '', temp,
num= this.toString().split('.'), n=num[0];
while(n.length> 3){
temp= n.substring(n.length-3);
s= ','+temp+s;
n= n.slice(0, -3);
}
if(n) s= n+s;
if(num[1]) s+='.'+num[1];
return s;
}
var n= 10000000000.34;
n.commas() = returned value: (String) 10,000,000,000.34
Formatting a number can be handled elegantly with one line of code.
This code extends the Number object; usage examples are included below.
Code:
Number.prototype.format = function () {
return this.toString().split( /(?=(?:\d{3})+(?:\.|$))/g ).join( "," );
};
How it works
The regular expression uses a look-ahead to find positions within the string where the only thing to the right of it is one or more groupings of three numbers, until either a decimal or the end of string is encountered. The .split()
is used to break the string at those points into array elements, and then the .join()
merges those elements back into a string, separated by commas.
The concept of finding positions within the string, rather than matching actual characters, is important in order to split the string without removing any characters.
Usage examples:
var n = 9817236578964235;
alert( n.format() ); // Displays "9,817,236,578,964,235"
n = 87345.87;
alert( n.format() ); // Displays "87,345.87"
Of course, the code can easily be extended or changed to handle locale considerations. For example, here is a new version of the code that automatically detects the locale settings and swaps the use of commas and periods.
Locale-aware version:
Number.prototype.format = function () {
if ((1.1).toLocaleString().indexOf(".") >= 0) {
return this.toString().split( /(?=(?:\d{3})+(?:\.|$))/g ).join( "," );
}
else {
return this.toString().split( /(?=(?:\d{3})+(?:,|$))/g ).join( "." );
}
};
Unless it's really necessary, I prefer the simplicity of the first version though.
After so much searching, I generate a regex which accepts all formats
(\d+[-, ,(]{0,3}\d+[-, ,(,)]{0,3}\d+[-, ,(,)]{0,3}\d+[)]{0,2})
With the caveat that Intl.NumberFormat
and Number.toLocaleString()
are now there for this purpose in JavaScript:
The other answers using regular expressions all break down for decimal numbers (although the authors seem to not know this because they have only tested with 1 or 2 decimal places). This is because without lookbehind, JS regular expressions have no way to know whether you are working with the block of digits before or after the decimal point. That leaves two ways to address this with JS regular expressions:
Know whether there is a decimal point in the number, and use different regular expressions depending on that:
/(\d)(?=(\d{3})+$)/g
for integers/(\d)(?=(\d{3})+\.)/g
for decimalsUse two regular expressions, one to match the decimal portion, and a second to do a replace on it.
function format(num) {
return num.toString().replace(/^[+-]?\d+/, function(int) {
return int.replace(/(\d)(?=(\d{3})+$)/g, '$1,');
});
}
console.log(format(332432432))
console.log(format(332432432.3432432))
console.log(format(-332432432))
console.log(format(1E6))
console.log(format(1E-6))
Iteration isn't necessary
function formatNumber(n, separator) {
separator = separator || ",";
n = n.toString()
.split("").reverse().join("")
.replace(/(\d{3})/g, "$1" + separator)
.split("").reverse().join("");
// Strings that have a length that is a multiple of 3 will have a leading separator
return n[0] == separator ? n.substr(1) : n;
}
var testCases = [1, 45, 2856, 398868483992];
for ( var i in testCases ) {
if ( !ns.hasOwnProperty(i) ) { continue; }
console.info(testCases[i]);
console.log(formatNumber(testCases[i]));
}
Results
1
1
45
45
2856
2,856
398868483992
398,868,483,992
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
var num=numberWithCommas(2000000); //any number
console.log(num);
enter code here
Try this