正则表达式问题在这里!
以下是我可以获得的两种行:
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中写出来?
谢谢!
答案 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
字符开头。)