我怎么能写一个正则表达式匹配非贪婪?

我需要关于正则表达式匹配与非贪婪选项的帮助。

匹配模式为:

<img\s.*>

要匹配的文本是:

<html>
<img src="test">
abc
<img
src="a" src='a' a=b>
</html>

我在http://regexpal.com上测试

这个表达式匹配从<img到最后>的所有文本。我需要它与初始<img之后第一次遇到的>匹配,所以在这里我需要得到两个匹配,而不是我得到的一个。

我尝试了贪婪的?的所有组合,没有成功。

516413 次浏览

非贪婪的?工作得非常好。只是你需要在你要测试的正则表达式引擎中选择点匹配全部选项(你使用的引擎regexpal也有这个选项)。这是因为,当你使用.时,正则表达式引擎通常不匹配换行符。你需要显式地告诉它们你也想用.来匹配换行符

例如,

<img\s.*?>

没问题!

检查结果在这里

此外,阅读关于dot表现如何的各种正则表达式。

?操作数使匹配非贪婪。例如,.*是贪婪的,而.*?不是。所以你可以使用类似<img.*?>的东西来匹配整个标签。或<img[^>]*>

但是请记住,实际上不能用正则表达式解析整个HTML集。

这里的其他答案假设您有一个支持非贪婪匹配的正则表达式引擎,这是Perl 5中引入的扩展,并被广泛复制到其他现代语言中;但它绝非无处不在。

许多旧的或更保守的语言和编辑器只支持传统的正则表达式,它们没有控制重复操作符*贪婪的机制——它总是匹配尽可能长的字符串。

接下来的技巧是首先限制允许匹配的内容。而不是.*,你似乎在寻找

[^>]*

它仍然匹配尽可能多的某物;但是某物不只是.“任何字符”,而是“不是>的任何字符”。

根据应用程序的不同,您可能希望启用或不希望启用允许“任何字符”包含换行的选项。

即使您的正则表达式引擎支持非贪婪匹配,也最好阐明您的实际意思。如果这个是你的意思,你可能应该这样说,而不是依靠非贪婪匹配(希望,可能)做我的意思。

例如,一个像.*?><br/>这样在通配符后面带有尾随上下文的正则表达式将跳过任何嵌套的>,直到它找到尾随上下文(这里是><br/>),即使这需要跨越多个>实例和换行符(如果你允许的话),而[^>]*><br/>(甚至[^\n>]*><br/>,如果你必须显式禁止换行)显然不能也不会这样做。

当然,如果你需要处理<img title="quoted string with > in it" src="other attributes"> and perhaps <img title="nested tags">,这仍然不是你想要的,但在这一点上,你应该最终放弃使用正则表达式,就像我们一开始告诉你的那样。