67

快速搜索货币正则表达式会带来很多结果

我在选择一个时遇到的问题是,如果不测试所有边缘情况,就很难验证正则表达式。有没有人有经过彻底测试的美元正则表达式?

我唯一的要求是匹配的字符串是美国货币并解析为System.Decimal

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

方括号([ 和 ])中的元素是可选的。
下表描述了每个元素。

元素描述
ws 可选的空格。
标志 可选标志。
数字 范围从 0 到 9 的数字序列。
, 特定于文化的千位分隔符。
. 特定于文化的小数点符号。
小数位数 范围从 0 到 9 的数字序列。
4

13 回答 13

107

这里有一些来自 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})?$

数字:货币金额 US & EU(美分可选) 可以使用美式 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})?)$
于 2008-12-09T20:57:54.487 回答
22

我在 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}))\)$"
于 2008-12-09T21:20:00.260 回答
10

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

^-?(?: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 取决于语言环境,很难在正则表达式中制作,除非在构建它时。我假设数字按三分组,即使在某些文化(语言环境)中存在不同的规则。
在它周围添加空格是微不足道的。

于 2008-12-09T21:52:01.990 回答
3

如果您想考虑人为错误,您可以在匹配货币时使正则表达式更加宽容。我使用了 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
于 2013-01-05T17:15:13.767 回答
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})?)$

网络小提琴: https ://dotnetfiddle.net/1mUpX2

于 2014-12-15T19:16:44.267 回答
2

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

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

对于货币,我强烈推荐autoNumeric jQuery 插件。它维护得很好,他们基本上“想到了一切”我想要的货币。

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

请记住,这jquery.inputmask主要是关于控制值的格式,而autoNumeric具体是关于控制货币的格式。

于 2016-06-12T02:54:49.760 回答
2

正则表达式

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

于 2020-08-04T15:10:24.347 回答
1

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

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

于 2011-08-25T06:57:22.013 回答
1

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

^-?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 \)
于 2011-11-29T13:15:35.520 回答
1

我在这方面取得了成功(从上面的一些正则表达式中获取点点滴滴)。最多只能处理数千个,但扩展它应该不会太难

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)
}
于 2012-12-12T17:35:01.287 回答
1

这就是我使用的:

没有前导 + 或 -

^\$\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/

于 2016-07-07T21:41:50.493 回答
1

使用 Leandro 的答案,我^(?:[$]|)在开头添加了一个美元符号

^(?:[$]|)[+-]?[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
于 2018-06-29T00:49:34.570 回答
0

这个如何?更短更优雅

(?:\,|\.?\d)*
于 2021-12-08T16:18:14.203 回答