编辑:讨论时间越来越长,所以我决定更新答案。
相信您的原始正则表达式有效,我将在此答案的其余部分引用简化版本:
/\b(https?|ftp|file)/gi
现在,你尝试了这个:
/^(?!src="|>)\b(https?|ftp|file)/gi
^
这里的主要错误由插入符号标记:插入符号。这会迫使您的正则表达式从行首匹配,这就是它不匹配的原因。让我们删除它并继续:
/(?!src="|>)\b(https?|ftp|file)/gi
这一次,主要错误在于您对前瞻断言的概念。正如我在评论中解释的那样,这个断言是多余的,因为你是在说,“匹配http
or https
or ftp
or file
,只要这些都不是src="
or >
。” 这几乎是多余的,以至于这句话对我们来说甚至没有意义!相反,您想要的是一个后向断言:
/(?<!src="|>)\b(https?|ftp|file)/gi
^
为什么?因为您希望找到src="
或在您可能希望匹配的字符串>
后面。问题?JavaScript 不支持后向断言。所以,我提出了一个替代方案。诚然,它是有缺陷的(尽管不是 HTML 中断的原因,正如您所提到的)。在这里,固定:
/(.[^>"]|[^=]")\b(https?|ftp|file)/gi
^^^^^^^^^^^^
这确实是一个非直观的正则表达式,需要解释。它将我们的案例一分为二。假设我们有一个两个字符集。如果集合不>
以or结尾"
,那么我们不怀疑它;我们可以走了;匹配任何可能跟随的 URL。但是,如果它确实>
以or结尾"
,那么唯一“可原谅”的情况是第一个字符不是=
. 所以你看,这里有点逻辑诡计。
现在,至于为什么这可能会破坏您的 HTML。请务必使用 JavaScript replace
,并将第一个捕获的组替换回页面!如果你只是用虚无替换每个匹配项,你最终会“吃掉”两个字符集,我们只是想调查,而不是破坏。
html.replace(/(.[^>"]|[^=]")\b(https?|ftp|file)/gi,
function(match, $1, offset, original) {
return $1;
});