Я знаю, что использование регулярного выражения для анализа html обычно является не стартером, но я не хочу ничего такого умного …
Взяв этот пример
<div><!--<b>Test</b>-->Test</div> <div><!--<b>Test2</b>-->Test2</div>
Я хотел бы удалить ВСЕ, что не между <!--
и -->
чтобы получить:
<b>Test</b><b>Test2</b>
Метки гарантированно будут правильно совпадать (без закрытых / вложенных комментариев).
Какое регулярное выражение мне нужно использовать?
Замените шаблон:
(?s)((?!-->).)*<!--|-->((?!<!--).)*
с пустой строкой.
Краткое объяснение:
(?s) # enable DOT-ALL ((?!-->).)*<!-- # match anything except '-->' ending with '<!--' | # OR -->((?!<!--).)* # match '-->' followed by anything except '<!--'
Будьте осторожны при обработке (X) HTML с регулярным выражением. Всякий раз, когда части комментариев встречаются в атрибутах тегов или блоках CDATA, все идет не так.
Видя самый активный тег – это JavaScript, вот демо JS:
print( "<div><!--<b>Test</b>-->Test</div>\n<div><!--<b>Test2</b>-->Test2</div>" .replace( /((?!-->)[\s\S])*<!--|-->((?!<!--)[\s\S])*/g, "" ) );
который печатает:
<b>Test</b><b>Test2</b>
Обратите внимание, что поскольку JS не поддерживает флаг (?s)
, я использовал эквивалентный [\s\S]
который соответствует любому символу (включая символы разрыва строки).
Протестируйте его на Ideone здесь: http://ideone.com/6yQaK
И демо-версия PHP будет выглядеть так:
<?php $s = "<div><!--<b>Test</b>-->Test</div>\n<div><!--<b>Test2</b>-->Test2</div>"; echo preg_replace('/(?s)((?!-->).)*<!--|-->((?!<!--).)*/', '', $s); ?>
который также печатает:
<b>Test</b><b>Test2</b>
как видно на Ideone: http://ideone.com/Bm2uJ
Другая возможность – это
.*?<!--(.*?)-->.*?(?=<!--|$)
и заменить на
$1
См. Здесь, в Regexr
Если вы прочтете строку за строкой, это будет соответствовать любому до первого комментария, поместить содержимое первого содержимого в группу 1 и затем сопоставить что-либо до конца строки или следующего комментария.
s/-->.*?<--//g strips off anything between "-->" and the next "<--" s/^.*?<--// strips off from the beginning to the first occurence of "<--" s/-->.*?$// strips off from the last occurence of "-->" to the end
.*
соответствует любому количеству символов и .*?
соответствует наименьшему количеству символов, так что шаблон отверстия соответствует
^
обозначает начало строки и $ для конца