我认为我为我需要的东西创建了一个有效的正则表达式。只是想知道是否有人可以打破它或看到更短的方式来编写它。
正则表达式应该验证以下内容......
所以这里有一些有效的例子......
9
$9
$0.99
($999,999.99)
(999999)
($999999)
(999,999)
99,999.9
这就是我的想法:
^\$?(((\d{1,6}(\.\d{1,2})?)|(\d{1,3},\d{3}(\.\d{1,2})?)|\(((\d{1,6}(\.\d{1,2})?)|(\d{1,3},\d{3}(\.\d{1,2})?))\)))$
更正,我的规格是错误的,如果使用美元符号,它必须在括号内。
答案 0 :(得分:10)
这是一个较短的选择(对你的114个56个字符),它几乎适用于所有正则表达式:
^\$?(?=\(.*\)|[^()]*$)\(?\d{1,3}(,?\d{3})?(\.\d\d?)?\)?$
示例:http://www.rubular.com/r/qtYHEVzVK7
说明:
^ # start of string anchor
\$? # optional '$'
(?= # only match if inner regex can match (lookahead)
\(.*\) # both '(' and ')' are present
| # OR
[^()]*$ # niether '(' or ')' are present
) # end of lookaheand
\(? # optional '('
\d{1,3} # match 1 to 3 digits
(,?\d{3})? # optionally match another 3 digits, preceeded by an optional ','
(\.\d\d?)? # optionally match '.' followed by 1 or 2 digits
\)? # optional ')'
$ # end of string anchor
答案 1 :(得分:3)
根据您的示例,以下正则表达式将起作用:
/^(\$?(?(?=\()(\())\d+(?:,\d+)?(?:\.\d+)?(?(2)\)))$/gm
(注意:标志和分隔符取决于语言)
这个正则表达式设置了一个不必要的反向引用,仅仅是为了保存正则表达式长度。您可以忽略第二个反向引用。如果这是不能容忍的,表达式会变得相当长一些。
答案 2 :(得分:3)
你可以表达“一到六位数字;最后三位数字之前的逗号是可选的”比\d{1,3}(,?\d{3})?
更简洁。这也允许您只包含两个(\.\d{1,2})?
副本:一个用于正面,一个用于负面,而不是一个用于正面 - 不用逗号,一个用于带逗号,等等。
此外,\d{1,2}
可以略微缩短为\d\d?
,但我不确定这是否有所改善。
因此,除了(?(1))
之类的符号来测试是否设置了反向引用,这是我看到的最短版本:
^(\$?\d{1,3}(,?\d{3})?(\.\d\d?)?|\(\$?\d{1,3}(,?\d{3})?(\.\d\d?)?\))$
你的正则表达式中的一个可能不合需要的方面是,它们将允许类似$00,012.7
的东西,即使没有人使用这样的前导零。您可以通过要求第一个数字非零来解决这个问题,然后添加一个特殊情况来处理$0
和(0.12)
等等:
^(\$?(0|[1-9]\d{0,2}(,?\d{3})?)(\.\d\d?)?|\(\$?(0|[1-9]\d{0,2}(,?\d{3})?)(\.\d\d?)?\))$
编辑添加:使用像F.J这样的先行断言在他/她的回答中建议,后者可以缩短为:
^(?!\(.*[^)]$|[^(].*\)$)\(?\$?(0|[1-9]\d{0,2}(,?\d{3})?)(\.\d\d?)?\)?$