'Only add thousand separator before decimal comma

I have found a regex on stackoverflow to add a ',' or '.' after every third number depending on your language.

(\d)(?=(\d\d\d)+(?!\d))

The problem is that it also happens when we reach the decimal point like with for example:

5487445.46878

The result of that with the following code (and regex) is:

return number.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");

Which results in:

5,487,445.46,878

I'm using this regex when I'm converting a number depending on your language. In Dutch for example a comma is used as a seperator, so there I do the following:

return number.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1.")

Which results in

5.487.445,46.878

These of course need to become:

5,487,445.46878

and

5.487.445,4687

Does anybody know where I need to update the regex to ignore the decimal point?



Solution 1:[1]

You can try this:-

    function thousandsSeparator(input) {
    var output = input
    if (parseFloat(input)) {
        input = new String(input);
        var parts = input.split("."); 
        parts[0] = parts[0].split("").reverse().join("").replace(/(\d{3})(?!$)/g, "$1,").split("").reverse().join("");
        output = parts.join(".");
    }

    return output;
}

Solution 2:[2]

With ECMAScript 2018+ compliant RegExp, you can use

text = text.replace(/(?<!\.\d*)(\d)(?=(?:\d{3})+(?!\d))/g, "$1,")

See the regex demo. Details:

  • (?<!\.\d*) - a negative lookbehind that fails the match if there is a . and then zero or more digits immediately to the left of the current location
  • (\d) - any one digit captured into Group 1
  • (?=(?:\d{3})+(?!\d)) - a positive lookahead that requires one or more sequences of three digits not immediately followed with another digit immediately to the right of the current location.

See the JavaScript demo:

const re = /(?<!\.\d*)(\d)(?=(?:\d{3})+(?!\d))/g;
[
    {str: "123456789.123456789", expect: "123,456,789.123456789"},
    {str: "123456789", expect: "123,456,789"},
    {str: "12345678.123456789", expect: "12,345,678.123456789"},
    {str: "12345678",      expect: "12,345,678"},
    {str: "1234567.123456789",      expect: "1,234,567.123456789"},
    {str: "1234567",      expect: "1,234,567"}
].forEach(test);

function test(entry) {
    const result = entry.str.replace(re, "$1,");
    console.log(`Testing ${entry.str}, got ${result}, ${(result == entry.expect ? "OK" : "ERROR")}`);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Wiktor Stribiżew