Что касается сопоставления «СОБАКИ», а не тега: я бы так и сделал, но вместо этого использовал бы это регулярное выражение:
DOG(?![^<>]++>)
[^<>]++
соответствует одному или нескольким объектам, которые не являются угловыми скобками собственнически . Как только это будет сделано, если следующая вещь не '>'
, она немедленно сообщит о сбое - без возврата. Вы не можете стать более эффективным, чем это.
Однако ваша идея использовать просмотр за спиной, чтобы определить, находитесь ли вы внутри URL, не будет работать. Это потребовало бы совпадения с задним числом переменной длины, и PHP не поддерживает этого - очень мало вариантов регулярного выражения.
Я рекомендую вместо этого подход, основанный на чередовании. В одном регулярном выражении вы сопоставляете либо полный HTML-тег, либо полный URL-адрес, либо ваше слово:
<[^<>]++>
|
(https?|ftp|file)://[A-Z0-9+&@#/%?=~_|$]++(?:[?!:,.;-]++[A-Z0-9+&@#/%=~_|$]++)*+
|
DOG
Используйте preg_replace_callback
, чтобы применить регулярное выражение, и в обратном вызове вы проверите, что оно соответствует. Если это тег или URL, подключите его снова; если это «СОБАКА», замените ее на «CAT».
Это предполагает, что каждая угловая скобка в файле является частью HTML-тега. Если ваши файлы могут содержать комментарии SGML, вам придется добавить для них альтернативу, перед , для тегов HTML. То же самое касается разделов CDATA. И, конечно, значения атрибутов также могут содержать угловые скобки. По моему опыту, это крайне редко, но при необходимости это тоже можно сделать.