如何在+符号上强制最大计数检测

时间:2013-09-05 21:57:01

标签: regex

正则表达式问题在这里!

以下是我可以获得的两种行:

a b c d COMMENT
a b c d vs e

我只想解析第一行

这是我要做的:

^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+((v(?!s)|[^v]).+)$

这会干净地解析任何这种行,而不是vs e完成.....除非我有多个空格,如下所示:

a b c d  vs e

我试图找到一种方法来指定负向前瞻之前的\s+应该意味着“占用所有可能的空间”而不是它当前所做的

我如何在Regex中写出来?

谢谢!

2 个答案:

答案 0 :(得分:3)

实际上,在负面展望之前的\s+意味着“占用所有可能的空间”。问题出在其他地方。

当正则表达式引擎解析到vs之前的最后两个空格时,它使用\s+读取它们,然后正则表达式尝试匹配((v(?!s)|[^v]).+)

它尝试第一个替代v(?!s)当然失败了,所以它需要尝试另一个[^v]).+但是也失败,因为当前字符是v

这会强制正则表达式引擎回溯并让最后一个\s仅匹配一个空格,现在引擎会重新尝试匹配空格,后跟vs,首先它会尝试v(?!s)但失败是因为当前字符是一个空格,然后它再次尝试[^v]).+,现在它成功,因为[^v]匹配一个空格,然后.+负责该行的其余部分。

要解决此问题,您可以使用@ p.s.w.g解决方案,或者可以阻止正则表达式回溯上一个\s+读取的空格。

如果您使用的是Java,那么您可以这样做:

^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s++((v(?!s)|[^v]).+)$
                                   ^^
                   Note the double ++, this makes + possessive and prevents backtracking

或者在大多数其他正则表达式中,即使在Java中也可以这样做:

^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)(?>\s+)((v(?!s)|[^v]).+)$
                                 ^^^
                 Notice the atomic group, this prevents backtracking

答案 1 :(得分:1)

问题是第二个空格与组内的[^v]模式匹配。为了防止这种情况,我建议使用这种模式:

^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+((v(?!s)|(?!v)\S).+)$

这将确保在组的开头没有捕获空格(它必须以\S字符开头。)