Skip to main content

JavaScript: Number Formatting

Hello.

Let's do a bit of JavaScript.

"Number Formatting" I mean in the title is as such:

  • 100 is formatted to 100
  • 1000 is formatted to 1,000
  • 10000 is formatted to 10,000
  • 123456 is formatted to 123,456
  • 9876543210 is formatted to 9,876,543,210
  • 1123.58 is formatted to 1,123.58

By adding a comma separator every three digits.

We can achieve that through:

  1. A loop.

    Using for — backwards loop.

    BUT!

    Before that, we need to separate —

    • the negative sign — if exists,
    • the digits part — this part is the subject of the formatting,
    • and the decimals part.

    Then lump everything together as the final result.

  2. Power of regular expression. 💪👺💪

Let us begin.


Loop Method

As I've mentioned above, this has separation stages, then the loop.

You can read the comments in the code to understand the flow.

Usage examples:

Without comments:

Well. 🤔 That works. Mostly.


Regular Expression Method

I've found a RegExp pattern specifically for this.

💪👺💪
I am Mwahahaha. Ore!

Let me break it down.

First, capturing 3-digit pattern:

\d{3}

Combine it with positive lookahead — looks ahead for groups of exactly three digits (3, 6, 9, 12 digits, etc.):

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

Add a pattern gate with a negative lookahead — ensures that after those groups of 3 digits, there are no more digits left. Meaning we are counting backwards from the end of the number:

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

Lastly, we need a final gate to stop the RegExp from matching the very beginning of the number:

\B(?=(\d{3})+(?!\d))

⬆️ Capital \B matches a position inside a word / number (that is, between two digits). Whilst \b matches the edge of a word (word boundary).

Final RegExp pattern:

We can then use replace method combined with that RegExp pattern — without input validation:

I do not put input validation there to emphasise how efficient the code is by employing a proper, clever regular expression. It works with negative number and decimals.

Usage examples:

And of course, if we need to make the separator to be flexible, add another parameter to the function. As such:

That digitSeparator. The default value is a comma (,). You can pass anything else. For instance, a period / dot (.). Make sure the number value type is a string.

Example:


Right. Let's take a moment to observe the pattern.

This brilliant RegExp pattern —

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

— is a classic one. I did not come up with that.


How It Operates

Let's use 1234567 as an example.

Positions between digits
  1. At Position B (between 1 and 2):

    • Is it a \B? Yes, it's inside the number.
    • Looking ahead: are there groups of 3 digits all the way to the end?
    • Yes! It sees 234 and 567 followed by the end of the line.
    • Match! A comma is placed after 1 ➡️ 1,
  2. At Position E (between 4 and 5):

    • Is it a \B? Yes.
    • Looking ahead: are there groups of 3 digits all the way to the end?
    • Yes! It sees 567 followed by the end of the line.
    • Match! A comma is placed after 4 ➡️ 4,
  3. Result: 1,234,567

Once more to appreciate it:

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

Whoever wrote that was playing chess with character boundaries. Using lookaheads to walk backwards from the end of a string while matching forwards from the front? Absolutely mental.

It's one of those bits of code where we look at it, head hurts for five minutes, and then when it clicks we go —

You absolute genius.

That's it, then. Thanks for visiting. Cheers! 👋

Monkey Raptor uses cookies for analytics, advertisements, and functionality. More info on Privacy Policy