正则表达式 c# 可选组 - 应该贪婪吗?
Posted
技术标签:
【中文标题】正则表达式 c# 可选组 - 应该贪婪吗?【英文标题】:regex c# optional group - should act greedy? 【发布时间】:2011-07-10 01:16:42 【问题描述】:有正则表达式~像这样:
blablabla.+?(?:<a href="(http://.+?)" target="_blank">)?
如果我找到一个 url,我想捕获一个……找到了东西,但我没有得到链接(捕获总是空的)。现在,如果我像这样删除末尾的问号
blablabla.+?(?:<a href="(http://.+?)" target="_blank">)
这只会匹配末尾有链接的内容...现在是凌晨 2.40...我没有任何想法...
--编辑--
样本输入:
blablabla asd 1234t535 <a href="http://google.com" target="_blank">
预期输出:
match 0:
group 1: <a href="http://google.com" target="_blank">
group 2: http://google.com`
我只想要“http://google.com”或“”
【问题讨论】:
如果在最后一个末尾添加.*
会怎样?
“blablabla.+”的目的是什么?
如果您能提供一些示例输入和预期输出,那就太好了。
@amcashcow 匹配 SOMETHING 然后 STUFF 直到找到链接
@markijbema 不抱歉,没有 - 误报
【参考方案1】:
你在做一个全字符串匹配吗?如果是这样,请尝试将.*
添加到第一个正则表达式的末尾并查看它匹配的内容。第一个正则表达式的问题是它可以匹配 blablabla
之后的任何内容,因为 .+?
(导致空捕获),但括号部分仍然不会匹配 a
标记,除非它位于末尾字符串。顺便说一下,看看您的预期输出,捕获 1 将是 URL;由于开头的 ?:
,整个 html 标记周围的括号是非捕获的。
【讨论】:
但是.+?应该充当非贪婪 == 在 上停止 @argh:是的,如果字符串的其余部分与<a href ...
匹配,它会匹配,但这需要字符串的整个其余部分都是标签。
哈哈!知道了!谢谢耶利米 - 你引导我解决问题:blablabla.+?)
@argh:移动括号内的组有什么好处?
是的......好吧......它工作了一秒钟,但只是因为后来有一个链接没有 target="_blank" 标签......啊......我是在那里很高兴一秒钟......【参考方案2】:
你不应该需要 .+?一开始,正则表达式无论如何都会搜索整个输入
在空白之后你也有结束的“>”,这将限制你的匹配
(?:<a href="(http://.+?)" target="_blank".*?>)
regex test
【讨论】:
好的,对不起,我的示例不太精确......我需要在前面这个 blablabla - 基本上我需要从一个秃头形成的 HTML 中提取 url 到其他网站......所以他们做了类似的事情:公司名称shitty unclosed html tags
google.com" target="_blank"
好吧,你可以在它前面放任何你想要的东西,但除非你想限制匹配的 url,否则没有必要。如果您这样做,请尽可能具体
是的,这正是我想要做的【参考方案3】:
这是尾随?那是在做你。原因:通过将其标记为可选,您允许 .+?抓住它。
blablabla.*(?:<a href="((http://)?.*)".+target="_blank".*>)
我稍作修改....+?
与.*
基本相同,如果您的href 中可能没有任何内容(您表示想要“”),则需要将http 设为可选以及尾随文本。此外,.*
前面的target
表示您至少有一个空格或字符,但可能有更多(多个空格或其他属性)。 .*
在>
之前意味着您可以在后面有空格或其他属性。
如果没有<a href...>
,这根本不会匹配一行,但这就是你想要的,对吧?
如果您不需要捕获整个<a href...>
部分,则可以完全删除(?: ... )
。
如果属性没有按指定的顺序列出,这将失败……这是正则表达式不能真正用于解析 html 的原因之一。但是,如果您确定 href 将始终位于目标之前,那么这应该可以满足您的需要。
【讨论】:
"如果没有 ,这将根本不匹配一行,但这就是您想要的,对吧?" --> 不。在这种情况下,我们需要与空捕获组进行正匹配。以上是关于正则表达式 c# 可选组 - 应该贪婪吗?的主要内容,如果未能解决你的问题,请参考以下文章