What is “The Best” U.S. Currency RegEx?

六月ゝ 毕业季﹏ 提交于 2019-11-26 11:40:25

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.

The answer of Keng is perfect, I just want add that for working with 1 or 2 decimals (for third version) :

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

NET FIDDLE: https://dotnetfiddle.net/1mUpX2

This question is a few years old, so I wanted to give an updated answer.

I have used jQuery InputMask and it works very well for input/format masking (such as phone numbers, etc) but it does NOT really work well for currency from my experience.

For currency, I strongly recommend autoNumeric jQuery plugin. It's well-maintained and they've basically "thought of everything" I could want for currency.

I actually use a combination of both of these plugins for formatting phone numbers, number formats (ISBN, etc), as well as currencies (US currency mostly).

Keep in mind that jquery.inputmask is mostly about controlling a value's format, whereas autoNumeric is about specifically controlling the format of currency.

I'm using the following regular expression for currency validation:

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

You can also allow optional leading dollar sign:

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

You can easily add testing for parentheses instead of sign by adding

\( and \)

I was looking at this too and have come to the conclusion that it is best to build the regex based on the current culture. We can use the

CurrencyPositivePattern 
CurrencyGroupSeparator
CurrencyDecimalSeparator

properties of NumberFormatInfo to get the required format.

Edit: something like this

NumberFormatInfo nfi = CultureInfo.CurrentCulture.NumberFormat;
      // Assign needed property values to variables.
      string currencySymbol = nfi.CurrencySymbol;
      bool symbolPrecedesIfPositive = nfi.CurrencyPositivePattern % 2 == 0;
      string groupSeparator = nfi.CurrencyGroupSeparator;
      string decimalSeparator = nfi.CurrencyDecimalSeparator;

      // Form regular expression pattern.
      string pattern = Regex.Escape( symbolPrecedesIfPositive ? currencySymbol : "") + 
                       @"\s*[-+]?" + "([0-9]{0,3}(" + groupSeparator + "[0-9]{3})*(" + 
                       Regex.Escape(decimalSeparator) + "[0-9]+)?)" + 
                       (! symbolPrecedesIfPositive ? currencySymbol : ""); 

refer - http://msdn.microsoft.com/en-us/library/hs600312.aspx

I've had success with this (taking bits and pieces from some of the regexs above). Only handles up to thousands, but should be not too hard to extend that

case class CurrencyValue(dollars:Int,cents:Int)
def cents = """[\.\,]""".r ~> """\d{0,2}""".r ^^ {
  _.toInt
}
def dollarAmount: Parser[Int] = """[1-9]{1}[0-9]{0,2}""".r ~ opt( """[\.\,]""".r ~> """\d{3}""".r) ^^ {
  case x ~ Some(y) => x.toInt * 1000 + y.toInt
  case x ~ None => x.toInt
}
def usCurrencyParser = """(\$\s*)?""".r ~> dollarAmount ~ opt(cents) <~ opt( """(?i)dollars?""".r) ^^ {
  case d ~ Some(change) => CurrencyValue(d, change)
  case d ~ None => CurrencyValue(d, 0)
}

In case you want to account for human error you could make the the regex more forgiving when matching currency. I used Keng's 2nd nice regex and made it a bit more robust to account for typo's.

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

This will match any of these proper or mangled currency figures but not pick up the extra junk on the end after the space:

$46,48382
$4,648,382
$ 4,648,382
$4,648,382.20
$4,648,382.2
$4,6483,82.20
$46,48382 70.25PD
$ 46,48382 70.25PD

This is what I use:

Without leading + or -

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

With optional leading + or -

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

net fiddle: https://jsfiddle.net/compsult/9of63cwk/12/

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
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!