Ваш код в том виде, в каком он есть, не должен вызывать особых проблем с фреймами iframe и т. Д., Потому что там у вас обычно есть "
перед URL-адресом, а не пробел, как того требует ваш шаблон.
Однако здесь другое решение. Это может не сработать на 100%, если у вас есть один <
или >
в комментариях HTML или что-то подобное. Но в любом другом случае он должен хорошо вас обслуживать (и я не знаю, является ли это проблемой для вас или нет). Он использует отрицательный просмотр вперед, чтобы убедиться, что нет закрытия >
перед любым открытием <
(потому что это означает, что вы находитесь внутри тега).
$content = preg_replace('$(\s|^)(https?://[a-z0-9_./?=&-]+)(?![^<>]*>)$i', ' <a href="$2" target="_blank">$2</a> ', $content." ");
$content = preg_replace('$(\s|^)(www\.[a-z0-9_./?=&-]+)(?![^<>]*>)$i', '<a target="_blank" href="http://$2" target="_blank">$2</a> ', $content." ");
Если вы не знакомы с этой техникой, вот несколько подробностей.
(?! # starts the lookahead assertion; now your pattern will only match, if this subpattern does not match
[^<>] # any character that is neither < nor >; the > is not strictly necessary but might help for optimization
* # arbitrary many of those characters (but in a row; so not a single < or > in between)
> # the closing >
) # ends the lookahead subpattern
Обратите внимание, что я изменил разделители регулярных выражений, потому что теперь я использую !
в регулярном выражении.
Если вам не нужен первый подшаблон (\s|^)
для URL-адресов вне тегов, теперь вы можете удалить и его (и уменьшить переменные захвата в замене).
$content = preg_replace('$(https?://[a-z0-9_./?=&-]+)(?![^<>]*>)$i', ' <a href="$1" target="_blank">$1</a> ', $content." ");
$content = preg_replace('$(www\.[a-z0-9_./?=&-]+)(?![^<>]*>)$i', '<a target="_blank" href="http://$1" target="_blank">$1</a> ', $content." ");
И, наконец ... вы не собираетесь заменять URL-адреса, которые содержат якоря в конце? Например. www.hello.com/index.html#section1
? Если вы пропустили это случайно, добавьте #
к разрешенным символам URL:
$content = preg_replace('$(https?://[a-z0-9_./?=&#-]+)(?![^<>]*>)$i', ' <a href="$1" target="_blank">$1</a> ', $content." ");
$content = preg_replace('$(www\.[a-z0-9_./?=&#-]+)(?![^<>]*>)$i', '<a target="_blank" href="http://$1" target="_blank">$1</a> ', $content." ");
РЕДАКТИРОВАТЬ: А как насчет +
и %
? Есть также несколько других символов, которые могут появляться в URL без кодирования. См. это. КОНЕЦ ИЗМЕНЕНИЯ
Я думаю, это должно помочь вам. Однако, если бы вы могли предоставить пример, показывающий рабочие и неработающие URL-адреса (с имеющимся у вас кодом), мы могли бы фактически предоставить решения, которые протестированы для работы во всех ваших случаях.
Последняя мысль. Правильным решением было бы использовать парсер DOM. Затем вы можете просто применить регулярное выражение, которое у вас уже есть, только к текстовым узлам. Однако ваша забота о структуре HTML очень ограничена, и это делает вашу проблему снова регулярной (если у вас нет несогласованных '‹' или '>' в комментариях HTML или JavaScript или CSS на странице). Если у вас есть такие особые случаи, вам действительно стоит изучить парсер DOM. Ни одно из представленных здесь (пока) решений не будет в этом случае безопасным.
person
Martin Ender
schedule
25.09.2012
(\s|^)
это будет соответствовать только в том случае, если у вас есть пробел или строки, начинающиеся перед URL-адресом. Но внутри iframe и img у вас должен быть"
, не так ли? - person Martin Ender   schedule 26.09.2012