如何用正则表达式找到所有Markdown链接?
在Markdown中,有两种方式可以插入链接,一种是直接输入链接,比如:http://example.com,另一种是使用()[]的语法:(Stack Overflow)[http://example.com]。
我正在尝试写一个正则表达式,能够匹配这两种情况,并且如果是第二种情况,还能提取出显示的文本。
到目前为止,我有这个:
(?P<href>http://(?:www\.)?\S+.com)|(?<=\((.*)\)\[)((?P=href))(?=\])

但是这似乎没有匹配我在Debuggex中测试的两个案例:
http://example.com
(Example)[http://example.com]
我真的不明白为什么至少第一个没有匹配,是不是和我使用的命名组有关?如果可以的话,我希望继续使用,因为这是一个简化的表达式,用来匹配链接,而在实际例子中,这个表达式太长了,我不太想在同一个模式中重复两次。
我哪里做错了?还是说这根本就做不到?
编辑:我是在Python中做这个,所以会使用他们的正则表达式引擎。
相关问题:
1 个回答
你遇到的问题在于这个部分:(?<=\((.*)\)\[),因为Python的re模块不支持可变长度的回顾。
你可以用一种更方便的方法来实现你的需求,使用Python的新regex模块 (因为re模块的功能比较少)。
举个例子:(?|(?<txt>(?<url>(?:ht|f)tps?://\S+(?<=\P{P})))|\(([^)]+)\)\[(\g<url>)\])
模式细节:
(?| # open a branch reset group
# first case there is only the url
(?<txt> # in this case, the text and the url
(?<url> # are the same
(?:ht|f)tps?://\S+(?<=\P{P})
)
)
| # OR
# the (text)[url] format
\( ([^)]+) \) # this group will be named "txt" too
\[ (\g<url>) \] # this one "url"
)
这个模式使用了分支重置功能(?|...|...|...),可以在选择中保留捕获组的名称(或编号)。在这个模式中,由于?<txt>组在选择的第一个部分被打开,所以第二部分的第一个组会自动使用相同的名称。?<url>组也是如此。
\g<url>是对命名子模式?<url>的引用(就像一个别名,这样在第二部分就不需要重复写了)。
(?<=\P{P})用来检查url的最后一个字符是否不是标点符号(这对于避免闭合方括号很有用)。(我不太确定这个语法,可能是\P{Punct})