如何编写匹配非贪婪的正则表达式? [复制]

Posted

技术标签:

【中文标题】如何编写匹配非贪婪的正则表达式? [复制]【英文标题】:How can I write a regex which matches non greedy? [duplicate] 【发布时间】:2012-08-07 14:21:38 【问题描述】:

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

匹配模式是:

<img\s.*>

要匹配的文本是:

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

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

此表达式匹配从&lt;img 到最后一个&gt; 的所有文本。我需要它与在初始 &lt;img 之后遇到的第一个 &gt; 匹配,所以在这里我需要得到两个匹配项,而不是我得到的那个。

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

【问题讨论】:

你用什么语言运行正则表达式? 【参考方案1】:

非贪婪的? 工作得非常好。只是您需要在您正在测试的正则表达式引擎(regexpal,您使用的引擎,也有此选项)中选择 dot matches all 选项。这是因为,当您使用. 时,正则表达式引擎通常不匹配换行符。你需要明确告诉他们你也想用.匹配换行符

例如,

<img\s.*?>

工作正常!

检查results here。

另外,阅读各种正则表达式风格的 how dot behaves。

【讨论】:

还有一个技巧可以解决这个问题:因为 \s 表示“任何空白”,而“\S”表示“任何非空白”,[\s\S] 将匹配任何字符(如“.”,但包括换行符)!同样,您可以使用 [\d\D] 或 [\w\W]。这可能是一个非常方便的小“hack”,它肯定是一个非常有用的技巧。 甚至,在本例中,您可以使用:&lt;img[^&gt;]*&gt; 来实现相同的效果:因为“除&gt; 之外的任何字符”都包含新行! 很好的答案,但是 bash 怎么样? echo "bla" | grep -P '' 匹配整个字符串,尽管 ?运算符。 @Thorsten: -P 选择 Perl 模式并且 perldoc 说 *?是非贪婪的。确认可以在 10 年前的 Linux 和最近的 Linux 上工作。也许你误解了输出。 “grep”打印在某处匹配的任何行(完整)。添加“-o”以仅打印匹配项。 我打算在下面的行中找到模式。 line = "/ab[1].bc[2].cd[3]";模式="([a-zA-Z0-9].*?\[\\d*?\])";我可以在 TextFX、notepad++ 中找到多个匹配项,但在 java 中只能找到 1 个匹配项【参考方案2】:

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

但请记住,用正则表达式实际上无法解析整套 HTML。

【讨论】:

你的回答提醒了这一点:***.com/a/1732454/431 我觉得说*?*的非贪婪版本更清楚。【参考方案3】:

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

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

那么诀窍就是首先限制允许匹配的内容。而不是.*,您似乎正在寻找

[^>]*

仍然匹配尽可能多的something;但是 something 不仅仅是.“任何字符”,而是“任何不是&gt; 的字符”。

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

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

例如,像.*?&gt;&lt;br/&gt; 这样的通配符后带有尾随上下文的正则表达式将跳过任何嵌套的&gt;,直到找到尾随上下文(此处为&gt;&lt;br/&gt;),即使这需要跨越多个&gt;实例和换行符,如果你允许的话,[^&gt;]*&gt;&lt;br/&gt;(或者甚至[^\n&gt;]*&gt;&lt;br/&gt;,如果你必须明确禁止换行符)显然不能也不会这样做。

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

【讨论】:

以上是关于如何编写匹配非贪婪的正则表达式? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式贪婪与非贪婪模式

正则表达式:最小可能匹配或非贪婪匹配

python正则表达式贪婪与非贪婪模式

[ 转载 ] 什么是正则表达式的贪婪与非贪婪匹配

15.python正则匹配 元字符转义重复或捕获分组断言:零度断言负向零宽断言贪婪非贪婪引擎选项

简单聊一聊正则表达式中的贪婪匹配和非贪婪匹配