【问题标题】:Javascript regex: Find all URLs outside <a> tags - Nested TagsJavascript 正则表达式:查找 <a> 标签之外的所有 URL - 嵌套标签
【发布时间】:2016-06-03 21:15:38
【问题描述】:

我已经构建了这个正则表达式代码:

((https?|ftps?):\/\/[^"<\s]+)(?![^<>]*?>|[^<>]*?<\/)

第一组捕获 HTML 中的所有链接,第二组是负前瞻,将标签内的任何部分作为属性排除,将标签内的任何部分作为内容排除。

我希望只排除 &lt;a&gt; 标记 - 所以解决方案可能是将最后一个术语修改为:

[^<>]*?<\/a>

但是现在如果我有嵌套标签就会出现问题,例如&lt;b&gt;&lt;/b&gt;&lt;a&gt;中。

这是我正在处理的示例:https://regex101.com/r/lM3hC5/6(应该是 10 个匹配项)。

负前瞻对我来说仍然很棘手。我认为以下应该有效,但事实并非如此:

(?!<a.+?<\/a>)

https://regex101.com/r/hT1cG5/1

这些是对我有帮助的最后一次讨论:

【问题讨论】:

  • 这个问题还不够严重,不能停止依赖正则表达式从 HTML 中提取文本吗?使用 DOM 解析器。
  • @WiktorStribiżew 你到底是什么意思 DOM 解析器?像这样的东西? simplehtmldom.sourceforge.net/manual.htm
  • 我只是想知道这是否可能,因为为此目的,我的代码使用正则表达式非常简洁。
  • @user2943191 我在某处使用正则表达式阅读应该是最后一个选项..
  • 这是一个可能的DOM based solution

标签: javascript html regex hyperlink nested


【解决方案1】:

事实证明,最好的解决方案可能如下:

((https?|ftps?):\/\/[^"<\s]+)(?![^<>]*>|[^"]*?<\/a)

看起来只有以 quantifiers 而不是字符串开头的负前瞻才能正常工作。对于这种情况,实际上我们只能进行回溯。

同样,我们只是想确保 HTML 标记中的任何属性都不会被弄乱。然后我们从&lt;/a 开始回溯到第一个" 符号(因为它不是有效的URL 符号,但&lt;&gt; 符号带有嵌套标签)。

现在&lt;a&gt; 标签内的嵌套标签也可以正确找到。当然,代码并不完美,但它几乎可以与任何简单的 HTML 标记一起使用。只是你可能需要小心一点:

  • &lt;a&gt;标签内加引号;
  • 不要在没有任何属性的&lt;a&gt;标签上使用此算法(placeholders);
  • 您可能需要避免使用多个嵌套标签/行,除非&lt;a&gt; 标签内的 URL 在任何双引号之后。


这是一个非常好的和混乱的例子(不应该找到最后一个匹配,但它是):

https://regex101.com/r/pC0jR7/2

可惜这个lookahead不起作用:(?!&lt;a.*?&lt;\/a&gt;)

【讨论】:

  • 也许有人能找到更好的方法来优化这段代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多