Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regular Expression for formatting numbers in JavaScript

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 expression? I've gotten as far as something like this:

myString = myString.replace(/^(\d{3})*$/g, "${1},"); 

...and then realized this would be more complex than I think (and the regex above is not even close to what I need). I've done some searching and I'm having a hard time finding something that works for this.

Basically, I want these results:

  • 45 becomes 45
  • 3856 becomes 3,856
  • 398868483992 becomes 398,868,483,992

...you get the idea.

like image 773
Brandon Montgomery Avatar asked Feb 12 '10 18:02

Brandon Montgomery


People also ask

How do you format numbers in JavaScript?

JavaScript numbers can be formatted in different ways like commas, currency, etc. You can use the toFixed() method to format the number with decimal points, and the toLocaleString() method to format the number with commas and Intl. NumberFormat() method to format the number with currency.

How do you write numbers in regular expressions?

The [0-9] expression is used to find any character between the brackets. The digits inside the brackets can be any numbers or span of numbers from 0 to 9. Tip: Use the [^0-9] expression to find any character that is NOT a digit.

What is $1 in regex JS?

The $ number language element includes the last substring matched by the number capturing group in the replacement string, where number is the index of the capturing group. For example, the replacement pattern $1 indicates that the matched substring is to be replaced by the first captured group.

What is regex formatting?

A regex (regular expression) consists of a sequence of sub-expressions. In this example, [0-9] and + . The [...] , known as character class (or bracket list), encloses a list of characters. It matches any SINGLE character in the list.


2 Answers

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

like image 119
Tim Pietzcker Avatar answered Sep 21 '22 23:09

Tim Pietzcker


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.

like image 28
Speednet Avatar answered Sep 18 '22 23:09

Speednet