What is "The Best" U.S. Currency RegEx?

Viewed 120365

A quick search for currency regex brings up a lot of results.

The problem I have in choosing one is that regex is difficult to verify without testing all the edge cases. Does anyone have a regex for U.S. currency that has been thoroughly tested?

My only requirement is that the matched string is U.S. currency and parses to System.Decimal:

[ws][sign][digits,]digits[.fractional-digits][ws] 

Elements in square brackets ([ and ]) are optional. 
The following table describes each element. 

ELEMENT             DESCRIPTION
ws                  Optional white space.
sign                An optional sign.
digits              A sequence of digits ranging from 0 to 9.
,                   A culture-specific thousands separator symbol.
.                   A culture-specific decimal point symbol.
fractional-digits   A sequence of digits ranging from 0 to 9. 
13 Answers

here's some stuff from the makers of Regex Buddy. These came from the library so i'm confident they have been thoroughly tested.

Number: Currency amount (cents mandatory) Optional thousands separators; mandatory two-digit fraction

Match; JGsoft:
^[+-]?[0-9]{1,3}(?:,?[0-9]{3})*\.[0-9]{2}$

Number: Currency amount (cents optional) Optional thousands separators; optional two-digit fraction

Match; JGsoft:
^[+-]?[0-9]{1,3}(?:,?[0-9]{3})*(?:\.[0-9]{2})?$

Number: Currency amount US & EU (cents optional) Can use US-style 123,456.78 notation and European-style 123.456,78 notation. Optional thousands separators; optional two-digit fraction

Match; JGsoft:
^[+-]?[0-9]{1,3}(?:[0-9]*(?:[.,][0-9]{2})?|(?:,[0-9]{3})*(?:\.[0-9]{2})?|(?:\.[0-9]{3})*(?:,[0-9]{2})?)$

I found this regular expression on line at www.RegExLib.com by Kirk Fuller, Gregg Durishan

I've been using it successfully for the past couple of years.

"^\$?\-?([1-9]{1}[0-9]{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))$|^\-?\$?([1-9]{1}\d{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))$|^\(\$?([1-9]{1}\d{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))\)$"

Not thoroughly tested at all (I just wrote it!), but seems to behave correctly:

^-?(?:0|[1-9]\d{0,2}(?:,?\d{3})*)(?:\.\d+)?$

Test set:

0
1
33
555
4,656
4656
99,785
125,944
7,994,169
7994169
0.00
1.0
33.78795
555.12
4,656.489
99,785.01
125,944.100
-7,994,169
-7994169.23 // Borderline...

Wrong:
000
01
3,3
5.
555,
,656
99,78,5
1,25,944
--7,994,169
0.0,0
.10
33.787,95
4.656.489
99.785,01
1-125,944.1
-7,994E169

Note: Your System.Decimal is locale dependent, hard to make in regex, except perhaps when building it. I assumed digits being grouped by three, even if in some cultures (locales) there are different rules.
It is trivial to add whitespace around it.

regex_expression

/^[-]?[$]\d{1,3}(?:,?\d{3})*\.\d{2}$/ is what I came up with - I see similar answers, but I just used \d instead of [0-9]

Using Leandro's answer I added ^(?:[$]|) to the beginning to allow for a preceding dollar sign

^(?:[$]|)[+-]?[0-9]{1,3}(?:[0-9]*(?:[.,][0-9]{1})?|(?:,[0-9]{3})*(?:\.[0-9]{1,2})?|(?:\.[0-9]{3})*(?:,[0-9]{1,2})?)$

This matched

136,402.99
25.27
0.33
$584.56
1
00.2
3,254,546.00
$3,254,546.00
00.01
-0.25
+0.85
+100,052.00

Did Not Match

11124.52
234223425.345
234.
.5234
a
a.23
32.a
a.a
z548,452.22
u66.36

What about this one? Shorter and elegant

(?:\,|\.?\d)*
Related