实际上,\s+
前面的负面展望确实意味着“占据所有可能的空间”。问题出在其他地方。
vs
当正则表达式引擎在使用 读取它们之前解析到最后两个空格时\s+
,正则表达式会尝试匹配((v(?!s)|[^v]).+)
。
它尝试第一个选择v(?!s)
当然失败,所以它需要尝试另一个[^v]).+
但也失败了,因为当前字符是 a v
。
这迫使正则表达式引擎回溯并让最后一个\s
匹配一个空格,现在引擎重新尝试匹配空格,然后是vs
,首先它尝试v(?!s)
但失败,因为当前字符是一个空格,然后它[^v]).+
再次尝试,现在它成功了因为[^v]
匹配一个空格然后.+
处理该行的其余部分。
要解决此问题,您可以使用 @pswg 解决方案,或者您可以防止正则表达式回溯 last 读取的空格\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