如何编写匹配非贪婪的正则表达式? [复制]
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上测试
此表达式匹配从<img
到最后一个>
的所有文本。我需要它与在初始 <img
之后遇到的第一个 >
匹配,所以在这里我需要得到两个匹配项,而不是我得到的那个。
我尝试了所有非贪婪?
的组合,但没有成功。
【问题讨论】:
你用什么语言运行正则表达式? 【参考方案1】:非贪婪的?
工作得非常好。只是您需要在您正在测试的正则表达式引擎(regexpal,您使用的引擎,也有此选项)中选择 dot matches all 选项。这是因为,当您使用.
时,正则表达式引擎通常不匹配换行符。你需要明确告诉他们你也想用.
匹配换行符
例如,
<img\s.*?>
工作正常!
检查results here。
另外,阅读各种正则表达式风格的 how dot behaves。
【讨论】:
还有一个技巧可以解决这个问题:因为 \s 表示“任何空白”,而“\S”表示“任何非空白”,[\s\S] 将匹配任何字符(如“.”,但包括换行符)!同样,您可以使用 [\d\D] 或 [\w\W]。这可能是一个非常方便的小“hack”,它肯定是一个非常有用的技巧。 甚至,在本例中,您可以使用:<img[^>]*>
来实现相同的效果:因为“除>
之外的任何字符”都包含新行!
很好的答案,但是 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】:
?
操作数使匹配非贪婪。例如。 .*
是贪婪的,而 .*?
不是。所以你可以使用<img.*?>
之类的东西来匹配整个标签。或<img[^>]*>
。
但请记住,用正则表达式实际上无法解析整套 HTML。
【讨论】:
你的回答提醒了这一点:***.com/a/1732454/431 我觉得说*?
是*
的非贪婪版本更清楚。【参考方案3】:
这里的其他答案假设您有一个支持非贪婪匹配的正则表达式引擎,这是 Perl 5 中引入的扩展,并被广泛复制到其他现代语言;但它绝不是无处不在的。
许多较旧或更保守的语言和编辑器仅支持传统的正则表达式,它们没有控制重复运算符 *
的贪婪的机制 - 它总是匹配可能的最长字符串。
那么诀窍就是首先限制允许匹配的内容。而不是.*
,您似乎正在寻找
[^>]*
仍然匹配尽可能多的something;但是 something 不仅仅是.
“任何字符”,而是“任何不是>
的字符”。
根据您的应用程序,您可能希望也可能不希望启用允许“任何字符”包含换行符的选项。
即使您的正则表达式引擎支持非贪婪匹配,最好还是说明您的实际意思。如果这是你的意思,你可能应该这样说,而不是依赖非贪婪匹配(希望,可能)按我的意思行事。
例如,像.*?><br/>
这样的通配符后带有尾随上下文的正则表达式将跳过任何嵌套的>
,直到找到尾随上下文(此处为><br/>
),即使这需要跨越多个>
实例和换行符,如果你允许的话,[^>]*><br/>
(或者甚至[^\n>]*><br/>
,如果你必须明确禁止换行符)显然不能也不会这样做。
当然,如果你需要处理<img title="quoted string with > in it" src="other attributes"> and perhaps <img title="nested tags">
,这仍然不是你想要的,但在这一点上,你应该最终放弃使用正则表达式,就像我们一开始就告诉你的那样。
【讨论】:
以上是关于如何编写匹配非贪婪的正则表达式? [复制]的主要内容,如果未能解决你的问题,请参考以下文章