如何使用正则表达式找到所有Markdown链接?

Sam*_*ett 8 python regex markdown

在Markdown中有两种放置链接的方法,一种是只输入原始链接,例如:http://example.com,另一种是使用()[]语法:.(Stack Overflow)[http://example.com ]

我正在尝试编写一个可以匹配这两个的正则表达式,如果它是第二个匹配也捕获显示字符串.

到目前为止我有这个:

(?P<href>http://(?:www\.)?\S+.com)|(?<=\((.*)\)\[)((?P=href))(?=\])
Run Code Online (Sandbox Code Playgroud)

正则表达式可视化

Debuggex演示

但这似乎与我在Debuggex中的两个测试用例中的任何一个都不匹配:

http://example.com
(Example)[http://example.com]
Run Code Online (Sandbox Code Playgroud)

真的不确定为什么第一个不匹配,是否与我对命名组的使用有关?如果可能的话,我想继续使用,因为这是一个简化的表达式来匹配链接,在实际例子中,我觉得在同一模式中的两个不同位置复制它太长了.

我究竟做错了什么?或者这根本不可行?

编辑:我在Python中这样做,所以将使用他们的正则表达式引擎.

Cas*_*yte 8

你的模式不起作用的原因在于:(?<=\((.*)\)\[)因为Python的re模块不允许变长的lookbehind.

您可以使用Python的新正则表达式模块 以更方便的方式获得您想要的内容(因为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"
)
Run Code Online (Sandbox Code Playgroud)

此模式使用分支重置功能(?|...|...|...),该功能允许在交替中保留捕获组名称(或数字).在该模式中,由于该?<txt>组首先在交替的第一个成员中打开,因此第二个成员中的第一个组将自动具有相同的名称.同?<url>组也是如此.

\g<url>是对命名子模式的引用?<url>(就像别名一样,这样就不需要在第二个成员中重写它了.)

(?<=\P{P})检查url的最后一个字符是否不是标点符号(例如,有助于避免关闭方括号).(我不确定语法,可能是\P{Punct})