Мой вопрос аналогичен этому вопросу:
Как имитировать поведение автоматической привязки StackOverflow
Однако это решение не работает для смешанного контента, который уже может содержать ссылки – любые URL-адреса, уже находящиеся внутри тегов 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>
Загрузите строку в формате HTML в ta DOM parser, перейдите по текстовым узлам и проверьте URL. Убедитесь, что родитель текстового узла не является тегом <a>
, поэтому вы знаете, что текст, который вы получаете, еще не находится в ссылке. Теперь найдите все URL-адреса, преобразуйте их в теги <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>
Он производит этот вывод :
<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>