Regex “什么是”呢;“最好的”;美国货币正则表达式?

Regex “什么是”呢;“最好的”;美国货币正则表达式?,regex,currency,Regex,Currency,快速搜索currency regex将显示 我选择其中一个的问题是,如果不测试所有的边缘情况,正则表达式很难验证。是否有人拥有经过彻底测试的美元正则表达式 我唯一的要求是匹配的字符串是美国货币,并解析为System.Decimal: [ws][sign][digits,]digits[.fractional-digits][ws] Elements in square brackets ([ and ]) are optional. The following table describe

快速搜索currency regex将显示

我选择其中一个的问题是,如果不测试所有的边缘情况,正则表达式很难验证。是否有人拥有经过彻底测试的美元正则表达式

我唯一的要求是匹配的字符串是美国货币,并解析为
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. [ws][sign][digits,]digits[.小数位数][ws] 方括号([和])中的元素是可选的。 下表描述了每个元素。 元素描述 ws可选空白。 签署一个可选的标志。 数字从0到9的一系列数字。 ,一个特定于区域性的符号。 . 特定于区域性的小数点符号。 小数位数从0到9的一系列数字。
这里有一些来自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})?$
Match; JGsoft:
^[+-]?[0-9]{1,3}(?:[0-9]*(?:[.,][0-9]{2})?|(?:,[0-9]{3})*(?:\.[0-9]{2})?|(?:\.[0-9]{3})*(?:,[0-9]{2})?)$
编号:货币金额(可选分) 可选数千个分离器;可选两位数分数

Match; JGsoft:
^[+-]?[0-9]{1,3}(?:,?[0-9]{3})*\.[0-9]{2}$
Match; JGsoft:
^[+-]?[0-9]{1,3}(?:,?[0-9]{3})*(?:\.[0-9]{2})?$
Match; JGsoft:
^[+-]?[0-9]{1,3}(?:[0-9]*(?:[.,][0-9]{2})?|(?:,[0-9]{3})*(?:\.[0-9]{2})?|(?:\.[0-9]{3})*(?:,[0-9]{2})?)$
编号:货币金额美国和欧盟(可选美分) 可以使用美式123456.78符号和欧式123.456.78符号。可选数千个分离器;可选两位数分数

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

我在www.RegExLib.com上找到了这个正则表达式,作者是柯克·富勒,格雷格·杜里山

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

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

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

^-?(?: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依赖于区域设置,很难在正则表达式中生成,除非在构建它时。我假设数字按三个分组,即使在某些文化(地区)中有不同的规则。

在它周围添加空格是很简单的。

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

CurrencyPositivePattern 
CurrencyGroupSeparator
CurrencyDecimalSeparator
属性以获取所需格式

编辑:类似这样的

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

请参阅-

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

^-?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 \)

我已经在这方面取得了成功(从上面的一些正则表达式中提取了一些片段)。仅处理多达数千个,但扩展它应该不太困难

case类CurrencyValue(美元:整数,美分:整数)
def cents=“”[\.\,]”“”.r~>“\d{0,2}”“”.r^^{
_托因先生
}
def dollarAmount:Parser[Int]=“[1-9]{1}[0-9]{0,2}”“”.r~opt(“[\.\,]”).r~>“\d{3}”“.r)^^{
案例x~一些(y)=>x.toInt*1000+y.toInt
案例x~无=>x.toInt
}
def usCurrencyParser=“”(\$\s*)?“.r~>dollarAmount~opt(美分)CurrencyValue(d,更改)
案例d~None=>CurrencyValue(d,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

Keng的答案是完美的,我只想补充一点,对于使用1或2个小数(对于第三个版本):

净小提琴:

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

我曾经使用过,它在输入/格式屏蔽(如电话号码等)方面效果很好,但根据我的经验,它在货币方面效果并不好

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

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

请记住,
jquery.inputmask
主要用于控制值的格式,而
autoNumeric
则专门用于控制货币的格式。

这就是我使用的:

不带前导+或-

^\$\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}$
带有可选的前导+或-

^\$\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}$
净小提琴:

我使用Leandro的答案在开头添加了
^(?:[$]|)
,以允许前面的美元符号

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

不匹配


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

我还要添加一个潜在问题-用括号代替符号。这是会计中相当常见的惯例。您引用的
MSDN
允许
00000000042
。布莱。@Robert levy:添加了参考msdn.microsoft.com/en-us/library/hs600312.aspx虽然我的测试不是权威性的,但这一个对我有效。接受:123 123.00$123.00 1234$1234$1234.00$1234.00拒绝:#123 1,2,34我发现的唯一问题是它接受123.4有效,工作人员希望123.4作为有效的美元金额。这是一种非常古老的方法,但这个正则表达式不能很好地处理可选的逗号。数字
11111111111.11
显然格式不正确,但这个正则表达式会匹配它。@Keng,我同意它满足OPs的需要,只是在做笔记,因为这是一个名为
什么是“最好的”美国货币正则表达式的问题的答案
我想我们可以通过替换
(?:,?[0-9]{3})来解决可选的逗号问题*
使用类似于
(?:(,[0-9]{3})*|([0-9]{3})*)
。到处都是逗号或没有逗号。这个答案可以通过正则表达式上方的示例数字来改进,而不是(或者)单词描述。@Keng现在是2020年,我仍然关心-正则表达式不需要