正则表达式没有正确结束[重复]

Posted

技术标签:

【中文标题】正则表达式没有正确结束[重复]【英文标题】:Regex doesn't end properly [duplicate] 【发布时间】:2013-08-14 00:12:36 【问题描述】:

我需要解析我的 html 页面来替换一些链接,这是链接<a href="/localLink:1144" title="Bas-rhin">Mauris nec</a> 的形式。问题是我的正则表达式没有正确结束,我认为这是因为 ".

这是我的正则表达式:

Regex r= new Regex("<a href=\"(/localLink:)(.*)\" title=\"(.*)\">(.*)</a>");

那个正则表达式不会在每个链接之后结束,第三组不包含标题属性,而是几乎所有的 html,直到我的最后一个 html。

我在这个网站上测试过:

http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx

那么,为什么第三组不直接在Bas-Rhin" 之后结束呢?

【问题讨论】:

...尤其是第一个答案... 我认为这个问题是相关的,请检查标记的答案:Using regular expressions to parse HTML: why not? @stephane 无需测试或阅读您的正则表达式:将.* 替换为.*?,它会变得不贪婪。也别忘了转义 你确定你在测试时没有混淆文本框吗?使用选项“CultureInvariant”,您的模式与我在 derekslager 上效果很好。 【参考方案1】:

你问的问题的答案(“那么,为什么第三组不直接在Bas-Rhin" 之后结束?”)是.* 是贪婪的,这意味着它会尽可能多地消耗。将其替换为.*?,使其消耗尽可能少。

如果您继续走这条路,您可能会遇到的许多问题的答案是正则表达式无法正确解析 HTML,因为 HTML 不是常规语言。如果您的语言具有嵌套匹配标记(例如 &lt;tag&gt; 匹配 &lt;/tag&gt; 匹配 )并且嵌套深度没有限制(HTML、C 系列语言、JSON 中就是这种情况) ,以及许多其他),正则表达式根本无法解析或验证它。

【讨论】:

这个答案似乎不正确,因为该模式使用文字 " 结束了 hreftitle 属性值的匹配所有子模式,因此不会有不需要的贪心匹配。 @collapsar 实际上,如果在&gt; 之前有任何其他带有" 的标签,并且在那之后的任何地方都有一个&lt;/a&gt;,它会一直消耗直到它匹配。所以该模式将匹配所有&lt;a href="/localLink:1144" title="title"&gt;Text&lt;/a&gt; More text here. &lt;a href="google.com"&gt;google&lt;/a&gt; 这当然是正确的,但不适用于 OP 给出的示例情况。最佳实践当然是强制不贪婪匹配或限制属性值的允许字符(即使用[^"]* 而不是.*)。【参考方案2】:
Regex r= new Regex("<a href=\"(/localLink:)(.*)\" title=\"(.*)\">(.*)</a>");

没有按预期工作,因为量词 (*) 在默认情况下是贪婪的,这意味着它们会捕获所有可能的东西(尽可能)。

要解决这个问题,你有几种方法:

1 最明显的:

通过添加问号使你的量词变得懒惰:(.*?)

2 最高效:

不要使用点,而是使用否定字符类。示例:

Regex r= new Regex("<a href=\"(/localLink:)([^]*)\" title=\"([^"]*)\">(.*?)</a>");

最后一个(.*?)可以替换为:

((?>[^<]+|<(?!/a>)*)

3个最合理的:

使用 agilitypack 或其他 html 解析器来提取所有“a”标签。您可以检查 href 是否符合您的要求。 (请注意,使用 xpath 您可以直接一步执行此检查)

Xpath 查询示例:

//a[contains(@href, 'localLink:')]

【讨论】:

【参考方案3】:

您的测试用例似乎没问题:

see here http://collapsar.ohost.de/pics/derek.png

【讨论】:

以上是关于正则表达式没有正确结束[重复]的主要内容,如果未能解决你的问题,请参考以下文章

细说正则表达式

Python-正则表达式1

正则表达式

正则表达式

正则表达式备忘录

正则表达式 - 匹配任何单词但忽略特定单词[重复]