PHP查找字符串中的URL并创建链接。如果尚未在链接中,请创建链接。

5

我希望能够在字符串中找到链接,但这些链接并没有被包含在一个链接中。

我的现有代码:

$text = "http://www.google.com is a great website. Visit <a href='http://www.google.com' >http://google.com</a>"
$reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";


if(preg_match($reg_exUrl, $text, $url)) {
   $links = preg_replace($reg_exUrl, '<a href="'.$url[0].'" rel="nofollow">'.$url[0].'</a>', $_page['content']['external_links']);

}

这个问题在于它返回了两次链接(这是它返回的内容):
<a href="http://www.google.com" rel="nofollow">http://www.google.com</a> is a great website. Visit <a href='<a href="http://www.google.com" rel="nofollow">http://www.google.com</a>' ><a href="http://www.google.com" rel="nofollow">http://www.google.com</a></a>

如果您只想计算尚未在<a>标签中的链接,则可以编辑您的正则表达式,以便检查您的链接是否没有被单引号或双引号包围。 - Cr3aHal0
这并不是那么简单,因为一个URL可以出现在HTML文档的多个位置(在href属性中,在src属性中,在DTD中或在JavaScript代码中)。因此,更好的方法是提取文档中不是链接节点(或脚本/样式节点)子节点的文本节点,并进行替换。 - Casimir et Hippolyte
使用 preg_replace_callback - Banago
2个回答

0
我在这里做出的假设是,您想匹配的URL将后跟空格、标点符号或位于行末。当然,如果有像 <a href="site">http://url </a> 这样的东西,它就不会工作得很好。如果您预计会遇到这种情况,请先用 \s+</a> 替换所有内容 </a>
$text = "http://www.google.com is a great website. Visit <a href='http://www.google.com' >http://google.com</a>, and so is ftp://ftp.theweb.com";
$reg_exUrl = "/((http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3})([\s.,;\?\!]|$)/";

if (preg_match_all($reg_exUrl, $text, $matches)) {
    foreach ($matches[0] as $i => $match) {
        $text = str_replace(
            $match,
            '<a href="'.$matches[1][$i].'" rel="nofollow">'.$matches[1][$i].'</a>'.$matches[3][$i],
            $text
        );
    }
}

输出:

http://www.google.com 是一个很棒的网站。访问 http://www.google.com' >http://google.comftp://ftp.theweb.com 也是如此。


这不会向已经是HTML链接的URL添加nofollow。 - Dan Hastings
@GillesMisslin 我想我可以再重新看一下这个问题。你用什么文本尝试了一下呢? - mike.k
这不是正确的方法。在这里使用 preg_replace_callback 是正确的函数。 - Banago

0
正确的做法是使用DOMDocument来解析你的HTML代码。然后递归地遍历子节点。跳过标签名为"a"的节点。然后分析textNodes,如果它们不是node的一部分,那么用一个节点替换textNode,并将textNode的值放入其中。
最后使用saveHTML来获取HTML字符串。
关于加载HTML的手册: https://www.php.net/manual/en/domdocument.loadhtml.php 关于遍历子节点的Stack Overflow问题: Loop over DOMDocument

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接