最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Enhancing regex of thousands separator? - Stack Overflow

programmeradmin4浏览0评论

I saw this beautiful script to add thousands separator to js numbers:

function thousandSeparator(n, sep)
{
    var sRegExp = new RegExp('(-?[0-9]+)([0-9]{3})'),
        sValue = n + '';
    if(sep === undefined)
    {
        sep = ',';
    }
    while(sRegExp.test(sValue))
    {
        sValue = sValue.replace(sRegExp, '$1' + sep + '$2');
    }
    return sValue;
}

usage :

thousandSeparator(5000000.125, '\,') //"5,000,000.125"

However I'm having a trouble accepting the while loop.

I was thinking to change the regex to : '(-?[0-9]+)([0-9]{3})*' asterisk...

but now , how can I apply the replace statement ?

now I will have $1 and $2..$n

how can I enhance the replace func?

p.s. the code is taken from here /

I saw this beautiful script to add thousands separator to js numbers:

function thousandSeparator(n, sep)
{
    var sRegExp = new RegExp('(-?[0-9]+)([0-9]{3})'),
        sValue = n + '';
    if(sep === undefined)
    {
        sep = ',';
    }
    while(sRegExp.test(sValue))
    {
        sValue = sValue.replace(sRegExp, '$1' + sep + '$2');
    }
    return sValue;
}

usage :

thousandSeparator(5000000.125, '\,') //"5,000,000.125"

However I'm having a trouble accepting the while loop.

I was thinking to change the regex to : '(-?[0-9]+)([0-9]{3})*' asterisk...

but now , how can I apply the replace statement ?

now I will have $1 and $2..$n

how can I enhance the replace func?

p.s. the code is taken from here http://www.grumelo.com/2009/04/06/thousand-separator-in-javascript/

Share Improve this question edited Dec 29, 2013 at 12:29 BenMorel 36.5k51 gold badges205 silver badges335 bronze badges asked May 16, 2012 at 5:01 Royi NamirRoyi Namir 149k144 gold badges491 silver badges829 bronze badges 6
  • 1 Btw, it fails on 5000000.125678 -> 5,000,000.125,678 – zerkms Commented May 16, 2012 at 5:05
  • @zerkms yep you right. grumelo.com/2009/04/06/thousand-separator-in-javascript – Royi Namir Commented May 16, 2012 at 5:06
  • Check out this question - there's a link to an example of how to do what you're trying. – Rob I Commented May 16, 2012 at 5:07
  • @RobI again , it still has a while loop. i think a better solution can be found....( or not) ...:) – Royi Namir Commented May 16, 2012 at 5:09
  • @Cylian i think we need positive look ahead (-?[0-9]+)([0-9]{3})(?=\.) but it not working... i mean - only replace numbers which in their right theres a DOT. – Royi Namir Commented May 16, 2012 at 5:18
 |  Show 1 more comment

5 Answers 5

Reset to default 8

There is no need to use replace, you can just add toLocaleString instead:

console.log((5000000.125).toLocaleString('en'));

More information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString

Your assumption

now i will have $1 and $2..$n

is wrong. You have two groups, because you have two sets of brackets.

    (-?[0-9]+)([0-9]{3})*
1.  ^^^^^^^^^^
2.            ^^^^^^^^^^

And then you repeat the second group. If it matches the second time, it overwrites the result of the first match, when it matches the third time, it overwrites ...

That means when matching is complete, $2 contains the value of the last match of that group.

First approach

(\d)(?=(?:[0-9]{3})+\b)

and replace with

$1,

See it on Regexr

It has the flaw that it does insert the comma also on the right of the dot. (I am working on it.)

Second approach

(\d)(?:(?=\d+(?=[^\d.]))(?=(?:[0-9]{3})+\b)|(?=\d+(?=\.))(?=(?:[0-9]{3})+(?=\.)))

and replace with

$1,

See it on Regexr

So now its getting a bit more complicated.

(\d)                   # Match a digit (will be reinserted)
(?:
    (?=\d+(?=[^\d.]))  # Use this alternative if there is no fractional part in the digit
    (?=(?:\d{3})+      # Check that there are always multiples of 3 digits ahead
    \b)                # Till a word boundary
    |                  # OR
    (?=\d+(?=\.))      # There is a fractional part
    (?=(?:\d{3})+      # Check that there are always multiples of 3 digits ahead
    (?=\.))            # Till a dot
)

Problem: does also match the fractional part if there is not the end of the string following.

Here is an ugly script to contrast your beautiful script.

10000000.0001 .toString().split('').reverse().join('')
.replace(/(\d{3}(?!.*\.|$))/g, '$1,').split('').reverse().join('')

Since we don't have lookbehinds, we can cheat by reversing the string and using lookaheads instead.

Here it is again in a more palatable form.

function thousandSeparator(n, sep) {

    function reverse(text) {
        return text.split('').reverse().join('');
    }

    var rx = /(\d{3}(?!.*\.|$))/g;

    if (!sep) {
        sep = ',';
    }

    return reverse(reverse(n.toString()).replace(rx, '$1' + sep));

}

How about this one:

result = "1235423.125".replace(/\B(?=(\d{3})+(?!\d))/g, ',') //1,235,423.125

Try this one:

result = subject.replace(/([0-9]+?)([0-9]{3})(?=.*?\.|$)/mg, "$1,$2");

Test here

发布评论

评论列表(0)

  1. 暂无评论