Skip to content

Instantly share code, notes, and snippets.

@jdsharp
Created March 3, 2011 04:17
Show Gist options
  • Save jdsharp/852326 to your computer and use it in GitHub Desktop.
Save jdsharp/852326 to your computer and use it in GitHub Desktop.
Quick and dirty code to insert commas after every 3 digits (also handles decimals correctly)
// via @DmitryBaranovsk
function dirtyCommas(num) {
return String(num).replace(/^\d+(?=\.|$)/, function (int) { return int.replace(/(?=(?:\d{3})+$)(?!^)/g, ","); });
}
@jdsharp
Copy link
Author

jdsharp commented Mar 3, 2011

That's cheating! Well..not really, very nicely done!

@jdalton
Copy link

jdalton commented Mar 3, 2011

that is hawt! I got thrown by the negative lookahead, (?!^), but it's zero-width so it works out. rock!

@jdalton
Copy link

jdalton commented Mar 3, 2011

if you don't mind rounding a bit you can do Math.max(0, num).toFixed(0).replace(/(?=(?:\d{3})+$)(?!^)/g, ',');, it avoids passing a function so it will work on older browsers that mess that up.

@mathiasbynens
Copy link

Some benchmarks for Dmitry’s regex: http://jsperf.com/number-format (Spoiler: it’s not only short and sweet, but also fast!)

@DmitryBaranovskiy
Copy link

@jdsharp, @jdalton, @mathiasbynens Thanks.

@jdalton Your solution wouldn’t work for numbers with a floating point. May be it’s ok. I would rather replace first regexp in my example to ^-?\d+(?=\.|$) to make it work with negative numbers too.
I wonder, could it be done with only one reasonable regexp? ;)

@jdalton
Copy link

jdalton commented Mar 3, 2011

@DmitryBaranovskiy Yap, mine avoids negatives and floats to make a pretty print version of the number.

For a single regexp you can do

String(value).replace(/(?=(?:\d{3})+\b)(?!\b\d{3}\b)/g, ",");

passing value as
"hiya -1000.45 and 100 faz, 200foos and 2534230 bars."

would produce

"hiya -1,000.45 and 100 faz, 200foos and 2,534,230 bars."

@DmitryBaranovskiy
Copy link

@jdalton Not that easy, try this:

`"hiya -1000.123123123 and 100 faz, 200foos and 2534230 bars."

Anyway solving it with one regexp is academical task, not very practical. Seems to be some monstrous regexp… or really smart one.

@DmitryBaranovskiy
Copy link

@jdalton Also it will choke on this:
"hiya -1000.45 and 100 faz, 200foos and 253423 bars."
Fix:
String(value).replace(/(?=(?:\d{3})+\b)(?!\b)/g, ",");

@jdalton
Copy link

jdalton commented Mar 4, 2011

Ya but still has a problem with the long decimal values.... I think a solution is close :D

@DmitryBaranovskiy
Copy link

@jdalton I think it even further now. Anyway I give up to solve it with one regexp. :)
Current solution is “good enough”.

@jdalton
Copy link

jdalton commented Mar 4, 2011

ok so the thing I could come up with is:

String(value).replace(/(\.\d+)|(?=(?:\d{3})+\b)(?!\b)/g, function(m, $1) { return $1 || ',' });

It requires passing a function but still just 1 regexp.

@IIsi50MHz
Copy link

I just applied jdalton's 2011.03.04 version to something I'm working on and found that I'll need a way to make it skip over dates. Example confusion: "...vol. 1, no. 4, pp. 4-9, July/August 1,995, concluded that..." (should contain "August 1995", rather than implying the nonsensical "July through August 1st, 995"). Guess I have my work cut out for me.

@paches86
Copy link

I've been trying several versions of this and it works great with numbers that are not thousand rounded.
for instance, 1234 goes 1,234.00.
But when I have 4000, I get a 4,0.00, so it basically removes 3 zeros off the thousands portion.
Does anyone have a clue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment