我知道使用正则表达式来解析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

10-07 23:42