正则表达式没有正确结束[重复]
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 不是常规语言。如果您的语言具有嵌套匹配标记(例如 <tag>
匹配 </tag>
或 匹配
)并且嵌套深度没有限制(HTML、C 系列语言、JSON 中就是这种情况) ,以及许多其他),正则表达式根本无法解析或验证它。
【讨论】:
这个答案似乎不正确,因为该模式使用文字"
结束了 href
、title
属性值的匹配所有子模式,因此不会有不需要的贪心匹配。
@collapsar 实际上,如果在>
之前有任何其他带有"
的标签,并且在那之后的任何地方都有一个</a>
,它会一直消耗直到它匹配。所以该模式将匹配所有<a href="/localLink:1144" title="title">Text</a> More text here. <a href="google.com">google</a>
这当然是正确的,但不适用于 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
【讨论】:
以上是关于正则表达式没有正确结束[重复]的主要内容,如果未能解决你的问题,请参考以下文章