正则表达式 - 负 lookahead with lazy limit?

Regex - negative lookahead with lazy limit?

提问人:Fabrício Matté 提问时间:4/19/2012 最后编辑:tchristFabrício Matté 更新时间:8/29/2012 访问量:1219

问:

我不是正则表达式专家,但几个小时后,我构建了这个正则表达式:

#\[url=(?!.*?<div onclick="unveil_spoiler.*?\[/url\])([^_\W]+?://.*?)\](.+?)\[/url\]#i

哪个不区分大小写:

\[url=(?!.*?<div onclick="unveil_spoiler.*?\[/url\])([^_\W]+?://.*?)\](.+?)\[/url\]

匹配模式,除非它包含介于 和 和 之间的字符串。[url=xxxx://yyyy]zzzz[/url]<div onclick="unveil_spoiler[url=[/url]

现在我正在尝试添加一个类似的检查,如果它包含 和 之间的匹配项,则不返回匹配项。我尝试了很多方法,但我似乎可以找到一个 100% 有效的方法。\[url.*?\]\[url=\[/url\]

首先,我尝试添加另一个否定的 lookforward,与我的正则表达式中已经存在的 lookahead 非常相似,它部分起作用,但后来似乎 lookahead 一直持续到行的末尾 - 直到最后 - 对于每场比赛,我希望 lookahead 像捕获组一样在第一个停止。\[/url\]\[/url\]

下面是用于调试的字符串:Here's a string for debugging:

[url=http://www.match.com]Match[/url][url=http://www.nomatch.com<div onclick="unveil_spoiler"]No match[/url][url=http://www.match.com]Match[/url][url=http://www.nomatch.com]<div onclick="unveil_spoiler" No match[/url]
[url=http://www.nomatch.com]No <div onclick="unveil_spoiler"match[/url][url=http://www.match.com]Match[/url][url=http://www.nomatch.com]No <div onclick="unveil_spoiler" match[/url][url=http://www.match.com]Match[/url]

[url=http://www.match.com]Match[/url][url=http://www.match.com][b]Match[/b][/url][url=http://www.match.com]Match[/url][url=http://www.match.com]Match[/url]

[url=http://www.thisshouldntmatch.com[url=http://www.match.com]Match[/url]This shouldn't match[/url]

[url=http://www.thisshouldntmatch.com[url=http://www.thisshouldntmatch.com[url=http://www.match.com]Match[/url]]This shouldn't match[/url]This shouldn't match[/url]

[url=http://www.thisshouldntmatch.com[url=http://www.match.com]Match[/url]This shouldn't match[/url][url=http://www.match.com]Match[/url]

[url=http://www.thisshouldntmatch.com]This shouldn't match[url=http://www.match.com]Match[/url][url=http://www.match.com]Match[/url][/url]

[url=http://www.match.com]Match[/url][url=http://www.match.com]Match[/url][url=http://www.match.com]Match[/url][url=http://www.match.com]Match[/url]

正则表达式发布在帖子的开头,它将与第一行中的 2 个匹配项完美匹配。现在我希望它在比赛内部时不返回匹配项,我尝试了这个正则表达式:\[url.*?\]

\[url=(?!.*?\[url.*?\].*?\[/url.*?\])(?!.*?<div onclick="unveil_spoiler.*?\[/url\])([^_\W]+?://.*?)\](.+?)\[/url\]

还有这个:

\[url=(?!.*?(?:<div onclick="unveil_spoiler|\[url.*?\]).*?\[/url\])([^_\W]+?://.*?)\](.+?)\[/url\]

当匹配项内部存在匹配项时,它不会返回匹配项,但随后它也会停止匹配它应该匹配的第一行(在示例字符串中)的第一个匹配项(并且与第一个正则表达式一样)。也就是说,它只会匹配每行的最后一个有效匹配项。\[url.*?\]

我认为这是前瞻的问题,它不会在第一时间停止,那么有什么方法可以让它变得懒惰/修复它吗?\[/url\]

任何帮助都是值得赞赏的。

php 则表达 -环视

评论


答:

1赞 Jack 4/19/2012 #1

这行得通吗?

\[url=[^\[<]*?\](?:(?!(\[url)|<).)*?\[\/url\]

http://regexr.com?30mna

评论

0赞 Fabrício Matté 4/19/2012
比我的更好,但它仍然只匹配每行中的第一个和最后一个有效匹配项,例如 编辑了第一篇文章以包含此字符串。[url=http://www.match.com]Match[/url][url=http://www.match.com]Match[/url][url=http://www.match.com]Match[/url][url=http://www.match.com]Match[/url]
0赞 Fabrício Matté 4/19/2012
我已经稍微编辑了您的第一个正则表达式,几乎符合我想要的,除了它与字符串中的第一个正则表达式不匹配,有什么方法可以解决这个问题吗?哦,秒尝试你的第二个。((\[url=(?!.*?(?:<div onclick="unveil_spoiler|\[url.*?\]).*?\[/url\])([^_\W]+?://.*?)\](.+?)\[/url\])|(?<=.*?\[url.*?)\[url=.*?url\])[url=
0赞 Jack 4/19/2012
检查我的更新。我认为它符合您的要求。这只是一个要搜索的额外 OR 条件。
0赞 Fabrício Matté 4/19/2012
\[url=[^\[]*?\][^\[]*?\[\/url\]我明白了,它确实适用于大多数字符串,但是,通过否定它不会匹配或检查,我真的不想阻止[][url=http://www.match.com][b]Match[/b][/url]<div onclick="unveil_spoiler[]\[url=.*?\[/url\]
0赞 Jack 4/19/2012
嗯,我明白了,也许你可以再发布几行你正在尝试匹配的示例文本。
2赞 Andrew Clark 4/19/2012 #2

我认为以下方法应该有效:

\[url=(?:(?!<div onclick="unveil_spoiler"|\[url.*?\].*?\[/url.*?\]).)*?([^_\W]+?://[^\[\]]*)\]((?:(?!\[/?url).)*)\[/url\]

http://rubular.com/r/7h9EJ0casb

评论

0赞 Fabrício Matté 4/19/2012
这似乎工作得很好,我正在用更多的例子来调试它以确保。
0赞 Andrew Clark 4/19/2012
@FabrícioMatté - 我只是做了一个轻微的编辑,因为我意识到捕获组没有做正确的事情。
0赞 Fabrício Matté 4/19/2012
是的,通过“轻微编辑”,您的意思是我会花一整晚的时间来理解它并适应其他 7 种模式,但它在这个范围内效果很好。谢谢。:)
0赞 Fabrício Matté 4/19/2012
哦,只是有一个小问题,它正在捕获与<div onclick="unveil_spoiler"[url=http://www.nomatch.com<div onclick="unveil_spoiler"]No match[/url][url=http://www.nomatch.com]<div onclick="unveil_spoiler" No match[/url]
0赞 Fabrício Matté 4/19/2012
我已经移动了展望,现在它工作正常\[url=(?!.*?<div onclick="unveil_spoiler")(?:(?!\[url.*?\].*?\[/url.*?\]).)*?([^_\W]+?://[^\[\]]*)\]((?:(?!\[/?url).)*)\[/url\]