什么是“最好的”美国货币RegEx?

时间:2008-12-09 20:05:33

标签: regex currency

快速搜索货币正则表达式会显示a lot of results

我在选择其中一个问题时遇到的问题是,如果不测试所有边缘情况,就很难验证正则表达式。我可以花很多时间在这上面,因为我相信其他数百名开发人员已经做过了。

是否有人拥有经过彻底测试的美国货币的正则表达式?

我唯一的要求是匹配的字符串是美国货币和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. 

12 个答案:

答案 0 :(得分:81)

这里有来自Regex Buddy制造商的一些东西。这些来自图书馆,所以我相信他们已经过彻底的测试。

数量:货币金额(必须分) 可选千位分隔符;强制性两位数分数

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

数字:货币金额(可选分) 可选千位分隔符;可选的两位数分数

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

数字:货币金额美国&欧盟(可选) 可以使用美式123,456.78表示法和欧式123.456,78表示法。可选千位分隔符;可选的两位数分数

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

答案 1 :(得分:15)

我在www.RegExLib.com上通过Kirk Fuller,Gregg Durishan在线找到了这个正则表达式

过去几年我一直在成功使用它。

"^\$?\-?([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}))\)$"

答案 2 :(得分:7)

根本没有经过彻底的测试(我只是写了它!),但似乎行为正确:

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

测试集:

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

注意:您的System.Decimal是依赖于语言环境的,很难在正则表达式中生成,除非在构建它时。我假设数字按三个分组,即使在某些文化(语言环境)中有不同的规则 在它周围添加空格是微不足道的。

答案 3 :(得分:3)

Keng的答案是完美的,我只想添加1或2位小数(第三版):

"^[+-]?[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

答案 4 :(得分:1)

这个问题已经有几年了,所以我想提供一个更新的答案。

我使用过jQuery InputMask并且它非常适合输入/格式屏蔽(例如电话号码等),但根据我的经验,它对货币的效果并不好。

对于货币,我强烈推荐autoNumeric jQuery插件。它维护得很好,而且他们基本上都在考虑所有事情并且#34;我想要货币。

我实际上使用这两个插件的组合来格式化电话号码,数字格式(ISBN等)以及货币(主要是美国货币)。

请注意,jquery.inputmask主要是关于控制价值的格式,而autoNumeric则是专门控制货币的格式。

答案 5 :(得分:0)

我也在考虑这个问题并得出结论,最好根据当前的文化构建正则表达式。 我们可以使用

CurrencyPositivePattern 
CurrencyGroupSeparator
CurrencyDecimalSeparator

NumberFormatInfo的属性以获取所需的格式。

编辑:类似这样的事情

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 : ""); 

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

答案 6 :(得分:0)

我正在使用以下正则表达式进行货币验证:

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

您还可以允许可选的领先美元符号:

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

您可以通过添加

轻松添加括号测试,而不是添加符号
\( and \)

答案 7 :(得分:0)

我已经成功了(从上面的一些正则表达式中获取点点滴滴)。只处理数千,但不应该太难扩展

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)
}

答案 8 :(得分:0)

如果您想要解决人为错误,您可以在匹配货币时使正则表达式更加宽容。我使用了Keng的第二个漂亮的正则表达式,并且为了解释拼写错误而使它更加强大。

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

这将匹配任何这些正确或受损的货币数字,但不会在空格后收拾额外的垃圾:

$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

答案 9 :(得分:0)

这就是我使用的:

不带领+或 -

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

使用可选的前导+或 -

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

网络小提琴: https://jsfiddle.net/compsult/9of63cwk/12/

答案 10 :(得分:0)

我使用莱安德罗的答案在开头添加了^(?:[$]|),以允许前面有一个美元符号

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

此匹配项

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

未匹配

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

答案 11 :(得分:0)

regex_expression

/^[-]?[$]\d{1,3}(?:,?\d{3})*\.\d{2}$/是我想出的-我看到了类似的答案,但是我只是使用\d而不是[0-9]