Regular Expression for formatting numbers in JavaScript
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 decimals
Use 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))
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.
This can be done in a single regex, no iteration required. If your browser supports ECMAScript 2018, you could simply use lookaround and just insert commas at the right places:
Search for (?<=\d)(?=(\d\d\d)+(?!\d))
and replace all with ,
In older versions, JavaScript doesn't support lookbehind, so that doesn't work. Fortunately, we only need to change a little bit:
Search for (\d)(?=(\d\d\d)+(?!\d))
and replace all with \1,
So, in JavaScript, that would look like:
result = subject.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
Explanation: Assert that from the current position in the string onwards, it is possible to match digits in multiples of three, and that there is a digit left of the current position.
This will also work with decimals (123456.78) as long as there aren't too many digits "to the right of the dot" (otherwise you get 123,456.789,012).
You can also define it in a Number prototype, as follows:
Number.prototype.format = function(){
return this.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
};
And then using it like this:
var num = 1234;
alert(num.format());
Credit: Jeffrey Friedl, Mastering Regular Expressions, 3rd. edition, p. 66-67
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