【问题标题】:regex matching links without <a> tag正则表达式匹配没有 <a> 标记的链接
【发布时间】:2014-08-30 08:55:40
【问题描述】:
(http([s]?):\/\/?)(([a-zA-Z0-9]+(\.?))+)([a-zA-Z0-9]+((\.[a-zA-Z]{2,5}){1,2})((\/[a-zA-Z0-9\?&=_\-\~:/?#[\]@!\$&'()\*\+,;]*)*)((\.[a-zA-Z]{2,5}){0,2}))

这是我的正则表达式,它可以很好地匹配字符串中的链接。但我不希望它选择每个链接。如果链接前面有"&gt;,或者后面有&lt;/a&gt;,则不应计算该链接。怎么办?

这些应该匹配:

adasdas http://www.stackoverflow.com asdasas
adasdasahttp://www.stackoverflow.com/something asdas

这些不应匹配:

adasdas<a href="somelink">           http://www.stackoverflow.com     </a>asdasas
adasdasa<a href="somelink">http://www.stackoverflow.com/something</a> asdas

我为什么需要这个?:我希望每个链接都可以点击,即使它不在锚标记之间。

【问题讨论】:

标签: php regex hyperlink anchor


【解决方案1】:

关于使用 regex 解析 html 的所有免责声明,如果您想使用 regex 来完成此任务,这将起作用:

$regex="~<a.*?</a>(*SKIP)(*F)|http://\S+~";

the demo

这个问题是这个问题中向"regex-match a pattern, excluding..."解释的技术的经典案例

交替| 的左侧匹配完整的&lt;a ...tags &lt;/a&gt; 然后故意失败,之后引擎跳到字符串中的下一个位置。右边匹配 url,我们知道它们是正确的,因为它们没有被左边的表达式匹配。

我放在右边的 url 正则表达式可以细化,使用适合您需要的任何内容即可。

参考

【讨论】:

  • 在你的末尾添加了我自己的模式 (&lt;a.*?&lt;/a&gt;(*SKIP)(*F)|),它成功了!谢谢。
  • 15 分钟前,我的声望分数不足以投票。但现在是 19 岁,我投了赞成票。再次感谢。
  • @zx81 这里的 (*SKIP)(*F) 是什么意思?
  • 如何使这个正则表达式与 Java/Apex 兼容,最初它给出了 Invalid string literal 错误,我能够通过转义一些字符来摆脱错误,但它不再起作用了,有什么帮助吗?
【解决方案2】:

您需要将 lookarounds 添加到您的正则表达式 c.f.:

【讨论】:

    【解决方案3】:

    这是我结合的一些 PHP 代码(来自此处的答案),用于为电子邮件和 URL 执行此操作的函数:

    function replace_links( $content ){
        $content = preg_replace('"<a[^>]+>.+?</a>(*SKIP)(*FAIL)|\b(?:https?)://\S+"', '<a href="$0">$0</a>', $content);
        $content = preg_replace('"<a[^>]+>.+?</a>(*SKIP)(*FAIL)|\b(\S+@\S+\.\S+)\S+"', '<a href="mailto:$0">$0</a>', $content);
        return $content;
    }
    

    演示: https://glot.io/snippets/g6nwd6amyo

    最新更新: https://gist.github.com/tripflex/0cc930c2afe5f4c73f2aed61cedf95d0

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-16
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多