正则表达式与数字字符串完全匹配

时间:2013-04-25 09:58:41

标签: regex

我有一个类似于600/-4.412/11的字符串和一个看起来像600/11

的字符串
[optional sign][float or integer]/[optional sign][float or integer]/[optional sign][float or integer]
[optional sign][float or integer]/[optional sign][float or integer]

示例:

1) 600/-4.412/11
2) 600/11

我需要找到一个匹配1的正则表达式和一个匹配2的正则表达式。但是两个表达式都不能选择/匹配另一个。凭借我谦逊的正则表达式知识,我设法建立了这个表达式:

([-+]?[0-9]+(\.?[0-9]+)?\/?){3}

根据http://gskinner.com/RegExr/,这个表达式的问题在于它匹配1)以及2)。希望有人可以解决这个问题或者至少告诉我为什么会发生这种情况,因为我希望我只需要将{3}更改为{2}以获得不同的匹配。

2 个答案:

答案 0 :(得分:1)

这是因为表达式中的几乎所有内容都是可选的。 必须出现的唯一内容是单个数字,因此您的表达式也会匹配007

因此,解决方案是使表达式的一部分成为必需的。有很多方法可以解决这个问题。一个不完全符合你的描述,但你应该考虑的恕我直言

([-+]?[0-9]+(\.[0-9]+)?(?=/|$))

此表达式将匹配两种类型的输入,但您可以通过查看匹配计数(2或3)来区分它们 - 这相当于在采用分支之前测试两个不同的表达式。

<强>更新

上面的表达式过于自由,因为它没有锚定在输入的开头和结尾。这是一个锚定的,因此如果输入包含任何虚假字符,则不匹配:

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

打破它:

^                   start matching at the beginning
(                   match the following:
[-+]?                   optional sign
[0-9]+(\.[0-9]+)?       integer or float
(                       either
/(?!$)                      a slash that's not trailing
|                       or
$                           end of input
)                   
){2,3}              do this exactly two or three times
$                   and make sure there is no other input

答案 1 :(得分:1)

问题

问题在于,您的正则表达式允许重复的子模式,即[-+]?[0-9]+(\.?[0-9]+)?\/?匹配,而不会将其限制为由/分隔的数字的每个部分。

对于您的问题中的此示例:600/11,第一次重复将与600/匹配,第二次重复将为1,第三次重复将为最后一次1

解决方案1 ​​

错误尝试

对于验证,您可以稍微更改它以使其按预期工作:

^([-+]?[0-9]+(\.[0-9]+)?(?:/|$)){3}$

(?:/|$)强制一个数字(浮点或整数)以/结束,或者它是字符串的结尾。这将有效地确保每个重复在相同的数字内不匹配。

前面添加了

^,后面添加了$,以确保该字符串正好有3个数字。

未删除的文字仍适用于正确的解决方案。

CORRECT解决方案

但是,上面的正则表达式是错误。它仍然允许1/2/3/之类的无效输入匹配(以/结尾)。我们需要在末尾添加一个额外的断言,以防止上述情况匹配:

^([-+]?[0-9]+(\.[0-9]+)?(?:/|$)){3}(?<!/)$

(?<!/)是一个零宽度负面后瞻,用于检查字符串结尾前的字符是否为/

解决方案2

在这种情况下,以[number]([delimiter][number]){repeat}形式编写正则表达式的麻烦不大,而不是摆弄([number][delimiter/ending]){repeat}形式。

以下答案将严格验证输入:

^[-+]?[0-9]+(\.[0-9]+)?(?:/[-+]?[0-9]+(\.[0-9]+)?){2}$

以上是为了匹配正好3个数字的情况。将2更改为1(或删除{2})以匹配2个数字。