PHP 在字符串中查找 URL 并创建链接。如果还没有链接

问题描述 投票:0回答:2

我想在字符串中查找链接尚未存在于链接中的 URL

我当前的代码:

$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>
php hyperlink preg-replace preg-match
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
        );
    }
}

输出:


0
投票

正确的做法是使用

DOMDocument
来解析 HTML 代码。然后递归地迭代子项。跳过 tagName 等于“a”的节点。然后分析
textNodes
,如果它们不是节点的一部分,则将
textNode
替换为节点,并将
textNode
值放入其中。

最后使用

saveHTML
获取html字符串。

关于加载html的手册: https://www.php.net/manual/en/domdocument.loadhtml.php

关于迭代子节点的 Stack Overflow 票证: 循环 DOMDocument


这是针对您的具体案例的另一个快速版本:

<?php


$input = "http://www.google.com is a great website. Visit <a href='http://www.google.com' >http://google.com</a>";


echo "Input:\n";
var_dump($input);


$output = preg_replace_callback("/(^|[^\"'>])(https?:\/\/[^ \n\r]+)/s",function($in){

    var_dump($in);
    $url = $in[2];
    return "<a rel=\"nofollow\" href=\"$url\">$url</a>";
}, $input);


echo "\n\nOutput:\n";
var_dump($output);

如您所见,我们使用技巧正则表达式来查找似乎不属于标签一部分的 http/https 链接。请注意,这对于像

<b>https://google.com</b>
这样的情况不起作用。如果您需要更高级的解决方案,您应该使用 DOMDocument 或者您可以检查每次出现 https? 之前的文本?标记。

© www.soinside.com 2019 - 2024. All rights reserved.