正则表达式的外观是增加宽度

时间:2016-07-02 17:05:18

标签: php regex regex-lookarounds

我有以下正则表达式:

\/.*?(?<!\\\\)(\\\\\\\\)*+\/[gimy]*

应该匹配正则表达式,不幸的是我发现这个正则表达式也匹配这行代码:

var a = b / c; // comment

由于具有分割符号/和注释//

regex101表示它匹配/ c; /

所以我试图做的是添加这样的负面预测:

\/.*?(?<!\\\\)(\\\\\\\\)*+\/[gimy]*(?!\/)

我打算排除那些后跟/字符的匹配。

它没有用!

regex101进行测试时,我发现它实际上是在添加宽度并匹配/ c; //

所以我最终选择了这个已经添加的宽度,并像这样编写我的表达式:

\/.*?(?<!\\\\)(\\\\\\\\)*+\/[gimy]*(?!\/| |[a-z]|[A-Z])

regex101 link

但是,我不觉得这是正确的做法!

那么我是否可以排除那些跟在其后面有/字符的匹配对象?

https://regex101.com/r/jR6vQ2/1

1 个答案:

答案 0 :(得分:0)

更新#1

你的问题是,虽然引擎正在采取步骤但是只有一个/它会看到另一个/,它不应该在那里(负向前瞻),所以它回溯并放弃一个角色(现在它正好在//之前,因为你有更多的模式,它会再次回溯。最后,它将.*?的匹配扩展为一个字符,并匹配自/被接受后现在满意的最后一个(?!\/)

在这种情况下,您应该通过调用原子组来告诉引擎失败并且不要继续回溯:

(?>/.+?/)(?!/)[gimy]*

修改正则表达式以包含转义斜杠:

(?m)/(?!/)[^/\\\n]*(?:\\.[^\n/\\]*)*/(?:[gmiy]+|\s|$)

说明:

 /                        # regex starting delimiter
 (?! / )                  # no `/` after
 [^/\\\n]*                # negated character class including `/` `\` `\n` (zero or more times)
 (?: \\ . [^\n/\\]* )*    # an escaped character followed by any character excluding a new-line and `\` (zero or more times)
 /                        # regex ending delimiter
 (?: [gmiy]+ | \s | $ )   # match any of these

Live demo