3

我想我为我需要的东西创建了一个有效的正则表达式。只是想知道是否有人可以打破它或看到更短的编写方法。

正则表达式应验证以下内容...

  • 美元符号可选
  • 负数用括号表示,而不是减号
  • 如果为负数,美元符号应在括号外
  • 逗号是可选的
  • 最大号码为 999999.99
  • 最小值为 (999999.99)
  • 不必提供小数,但如果提供,不超过两位数

所以这里有一些有效的例子......

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})?))\)))$

更正,我的规范是错误的,如果使用美元符号,它必须在括号内。

4

3 回答 3

11

这是一个较短的替代方案(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
于 2012-12-12T21:19:13.053 回答
3

鉴于您的示例,以下正则表达式将起作用:

/^(\$?(?(?=\()(\())\d+(?:,\d+)?(?:\.\d+)?(?(2)\)))$/gm

(注意:标志和分隔符取决于语言)

此正则表达式设置不必要的反向引用只是为了节省正则表达式长度。您可以忽略第二个反向引用。如果这是无法容忍的,则表达式将变得相当长。

看看这里:http ://regex101.com/r/fH3lV1

于 2012-12-12T21:14:52.943 回答
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?)?\))$

编辑添加:使用 FJ 在他/她的回答中建议的前瞻断言,后者可以缩短为:

^(?!\(.*[^)]$|[^(].*\)$)\(?\$?(0|[1-9]\d{0,2}(,?\d{3})?)(\.\d\d?)?\)?$
于 2012-12-12T21:16:23.613 回答