正则表达式将 Markdown 中的文本 URL 转换为链接

Regex to convert text URLs in Markdown to Links

我正在尝试将 markdown 文本中的文本链接(带有 FQDN,即没有相关 links)转换为 Markdown links。它工作正常,除非源降价已经将文本转换为 links。例如,这是源文本:

Login in to My site [https://example.com/](https://example.com/) and select Something > Select below details further.
(https://example.com/abc/1.html)

Also have a look at https://example.com/abc/1.html

我的正则表达式:/(?<!\]\()(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim.

预期:仅匹配第二个和第三个link。当前结果:匹配 3 URLs.

我尝试在末尾添加否定前瞻,类似于开头的否定后瞻,但这只是省略了 URL 的最后一个字符,这太糟糕了!

我在 NodeJS 中使用它。

这是 link 到 regex101 with the sample data

如果 "http" 之前的字符是左括号,您可以选择不通过简单地不匹配来指定 lookahead/lookbehind:

[^\[\(](https?|ftp):\/\/[^\s]*

但是如果你确实想排除格式 [x](y) 中的所有 URL,那么使用这个:

(?<!\]\()((?:https?|ftp):\/\/[^\s\]\)]*)(?:[\s\]\)](?!\()|$)

其中:

  • (?<!\]\() - 回顾断言以确保这不是 [x](y)
  • 中的 y
  • ( - 捕获 URL 部分
    • (?:https?|ftp):\/\/ - 匹配 URL
    • 的 http/ftp 部分
    • [^\s\]\)]* - 匹配 URL.
    • 的剩余部分
  • ) - URL
  • 捕获结束
  • (?: - 非捕获组
    • [\s\]\)] - 匹配 space 字符、右括号或右括号。我们需要匹配结尾的 bracket/parenthesis 的原因是允许 URL 的格式,例如(Check https://google.com)[Check https://google.com]
    • (?!\() - 前瞻断言以确保这不是 [x](y)
    • 中的 x
    • | - 或者
    • $ - 字符串结束
  • ) - 非捕获组结束

您可以使用模式来匹配您不想要的内容,并在第 1 组中捕获您想要的内容。

替换时可以利用replace的回调函数

您可以检查 id 组 1 是否存在。如果是这样,请替换为您的自定义替换件。如果不存在,则替换为全匹配

\[(?:https?|ftp):\/\/[^\]\[]+\]\([^()]*\)|((?:https?|ftp):\/\/\S+)

部分模式匹配:

  • \[匹配[
  • (?:https?|ftp):\/\/ 匹配协议之一和 ://
  • [^\]\[]+ 匹配除 []
  • 之外的任何字符 1+ 次
  • \] 匹配 ]
  • \([^()]*\) 匹配从 ()
  • |
  • ((?:https?|ftp):\/\/\S+)组 1 中捕获 url 格式

Regex demo

不匹配url中的括号:

\[(?:https?|ftp):\/\/[^\]\[]+\]\([^()]*\)|((?:https?|ftp):\/\/[^()\s]+)

Regex demo

或者在括号之间专门捕获一个url:

\[(?:https?|ftp):\/\/[^\]\[]+\]\([^()]*\)|\(((?:https?|ftp):\/\/\S+)\)|((?:https?|ftp):\/\/[^()\s]+)

Regex demo