PHP自动链接如果尚未链接

时间:2013-05-02 20:16:56

标签: php html

我的问题类似于这个问题:

How to mimic StackOverflow Auto-Link Behavior

但是,此解决方案不适用于可能已包含链接的混合内容 - 已在A <a href="http://stackoverflow.com">My Link</a>内部的任何网址都会被限制为<a href="<a href="http://stackoverflow.com">stackoverflow.com</a>">My Link</a>

这是所需的行为:

https://stackoverflow.com/ is a wonderful URL.

<a href="https://stackoverflow.com/">Has already been linked.</a>

<a href="https://stackoverflow.com/">https://stackoverflow.com/</a> is a wonderful URL.

<a href="https://stackoverflow.com/">Has already been linked.</a>

1 个答案:

答案 0 :(得分:1)

在ta DOM解析器中将字符串加载为HTML,迭代文本节点,并检查URL。确保文本节点的父级不是<a>标记,因此您知道您获得的文本尚未包含在链接中。现在,找到所有网址,将其转换为<a>标记,并在DOM中替换它们:

$doc = new DOMDocument();
$doc->loadHTML( $str);

$xpath = new DOMXpath($doc);
foreach( $xpath->query('//text()') as $text) {
    if( !($text->parentNode->tagName == "a")) {
        $frag = $doc->createDocumentFragment();
        $frag->appendXML( preg_replace('#(http://stackoverflow.com/)#', '<a href="$1">$1</a>', $text->data));
        $text->parentNode->replaceChild( $frag, $text);
    }
}

请注意,这依赖于正则表达式来识别URL,这是一项艰巨的任务。我建议找一个适合您需求的产品,正如目前使用的那样:

#(http://stackoverflow.com/)#

但是,鉴于此输入:

http://stackoverflow.com/ is a wonderful URL.

<a href="http://stackoverflow.com/">Has already been linked.</a>

<a href="http://stackoverflow.com/">http://stackoverflow.com/</a>

produces this output

<p><a href="http://stackoverflow.com/">http://stackoverflow.com/</a> is a wonderful URL. 

<a href="http://stackoverflow.com/">Has already been linked.</a> 

<a href="http://stackoverflow.com/">http://stackoverflow.com/</a></p>