Regex удалить все, что не является комментарием html.

Я знаю, что использование регулярного выражения для анализа html обычно является не стартером, но я не хочу ничего такого умного …

Взяв этот пример

<div><!--<b>Test</b>-->Test</div> <div><!--<b>Test2</b>-->Test2</div> 

Я хотел бы удалить ВСЕ, что не между <!-- и --> чтобы получить:

 <b>Test</b><b>Test2</b> 

Метки гарантированно будут правильно совпадать (без закрытых / вложенных комментариев).

Какое регулярное выражение мне нужно использовать?

Related of "Regex удалить все, что не является комментарием html."

Замените шаблон:

 (?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

EDIT II

И демо-версия 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 

.* соответствует любому количеству символов и .*? соответствует наименьшему количеству символов, так что шаблон отверстия соответствует

^ обозначает начало строки и $ для конца