Как искать URL-адреса, которые не находятся ни в одном теге html, а затем превращать их в гиперссылки?

Поэтому моя проблема заключается в том, что в одном и том же содержимом есть iframes, теги изображений и т. Д. У всех есть регулярные выражения, которые преобразуют их в правильный формат.

Последнее, что осталось, это обычный URL. Мне нужно регулярное выражение, которое найдет все ссылки, которые являются просто ссылками, а не внутри iframe, img или любого другого тега. В этом случае тегами являются обычные HTML-теги, а не BB.

В настоящее время я получил этот код как последний прогон рендеринга содержимого. Но он также будет реагировать на все другие вещи, сделанные выше (iframes и img renderings.) Таким образом, он идет и заменяет URL-адреса.

$output = preg_replace(array( '%\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))%s' ), array( 'test' ), $output); 

И мой контент выглядит примерно так:

 # dont want these to be touched <iframe width="640" height="360" src="http://somedomain.com/but-still-its-a-link-to-somewhere/" frameborder="0"></iframe> <img src="http://img.ruphp.com/php/here-is-a-img-url.jpg" border="0" /> # and only these converted http://google.com http://www.google.com https://www2.google.com<br /> www.google.com 

Как вы можете видеть, в конце ссылки также может быть что-то. После полного дня работы над регулярными выражениями этот последний <br /> был для меня кошмаром.

Описание

Это решение будет соответствовать URL-адресам, которые не входят в значения атрибутов тега, и заменят их чем-то новым.

Регулярное выражение соответствует как пропущенным вещам, так и вещам, которые вы заменили. Затем preg_match_callback выполняет внутреннюю функцию, которая проверяет, заполняется ли группа захвата 1 (это желаемый текст), и если это так возвращает изменение, в противном случае оно просто возвращает нежелательный текст.

Я использовал регулярное выражение для соответствия url с некоторыми незначительными изменениями, такими как преобразование неиспользуемых групп захвата () в группы без захвата (?:) . Это заставляет двигатель regex работать быстрее и упрощает модификацию выражения.

Исходное выражение: <(?:[^'">=]*|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*>|((?:[\w-]+:\/\/?|www[.])[^\s()<>]+(?:\([\w\d]+\)|(?:[^[:punct:]\s]|\/)))

введите описание изображения здесь

пример

Код

 <?php $string = '# dont want these to be touched <iframe width="640" height="360" src="http://somedomain.com/but-still-its-a-link-to-somewhere/" frameborder="0"></iframe> <img src="http://someotherdomain.com/here-is-a-img-url.jpg" border="0" /> # and only these converted http://google.com http://www.google.com https://www2.google.com<br /> www.google.com'; $regex = '/<(?:[^\'">=]*|=\'[^\']*\'|="[^"]*"|=[^\'"][^\s>]*)*>|((?:[\w-]+:\/\/?|www[.])[^\s()<>]+(?:\([\w\d]+\)|(?:[^[:punct:]\s]|\/)))/ims'; $output = preg_replace_callback( $regex, function ($matches) { if (array_key_exists (1, $matches)) { return '<a href="' . $matches[1] . '">' . $matches[1] . '<\/a>'; } return $matches[0]; }, $string ); echo $output; 

Вывод

 # dont want these to be touched <iframe width="640" height="360" src="http://somedomain.com/but-still-its-a-link-to-somewhere/" frameborder="0"></iframe> <img src="http://someotherdomain.com/here-is-a-img-url.jpg" border="0" /> # and only these converted <a href="http://google.com">http://google.com<\/a> <a href="http://www.google.com">http://www.google.com<\/a> <a href="https://www2.google.com">https://www2.google.com<\/a><br /> <a href="www.google.com">www.google.com<\/a>