Auto-converting numbers to comma-fied versions

Posted by Jeff Atwood on Stack Overflow See other posts from Stack Overflow or by Jeff Atwood
Published on 2009-07-25T14:59:15Z Indexed on 2010/04/23 17:43 UTC
Read the original article Hit count: 407

Filed under:
|
|
|

Given the following text

/feeds/tag/remote-desktop                               1320  17007    22449240
/feeds/tag/terminal-server                              1328  15805    20989040
/foo/23211/test                                         1490  11341    16898090

Let's say we want to convert those numbers to their comma-fied forms, like so

/feeds/tag/remote-desktop                             1,320  17,007  22,449,240
/feeds/tag/terminal-server                            1,328  15,805  20,989,040
/foo/23211/test                                       1,490  11,341  16,898,090

(don't worry about fixing the fixed-width ASCII spacing, that's a problem for another day)

This is the best regex I could come up with; it's based on this JavaScript regex solution from Regex Ninja Steven Levithan:

return Regex.Replace(s, @"\b(?<!\/)\d{4,}\b(?<!\/)", 
    delegate(Match match) {
        string output = "";
        string m = match.Value;
        int len = match.Length;
        for (int i = len - 1; i >= 0 ; i--)
        {                        
            output = m[i] + output;
            if ((len - i) % 3 == 0) output = "," + output;
        }
        if (output.StartsWith(","))
            output = output.Substring(1, output.Length-1);
        return output;
    });

In a related question, there is a very clever number comma insertion regex proposed:

text = Regex.Replace(text, @"(?<=\d)(?=(\d{3})+$)", ",")

However this requires an end anchor $ which, as you can see, I don't have in the above text -- the numbers are "floating" in the rest of the text.

I suspect there is a cleaner way to do this than my solution? After writing this, I just realized I could combine them, and put one Regex inside the other, like so:

return Regex.Replace(s, @"\b(?<!\/)\d{4,}\b(?<!\/)", 
    delegate(Match match) {
        return Regex.Replace(match.Value, @"(?<=\d)(?=(\d{3})+$)", ",");
    });

© Stack Overflow or respective owner

Related posts about regex

Related posts about .NET