0

我有一个看起来像这样的字符串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} 即可获得不同的匹配。

4

2 回答 2

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
于 2013-04-25T10:08:45.510 回答
1

问题

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

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

解决方案 1

错误的尝试

对于验证,您可以稍微更改它以使其按您想要的方式工作:

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

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

^在前面和$后面添加以确保字符串正好有 3 个数字。

未划掉的文本仍然适用于正确的解决方案。

正确的解决方案

但是,上面的正则表达式是错误的。它仍然允许无效输入,例如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 个数字的情况。更改21(或删除{2})以完全匹配 2 个数字。

于 2013-04-25T10:12:14.280 回答