使用PHP剥离HTML注释但是离开条件

Ian*_*Ian 6 php regex conditional comments strip

我目前正在使用PHP和正则表达式从页面中删除所有HTML注释.脚本效果很好......有点太好了.它删除了所有评论,包括我的条件评论.这是我得到的:

<?php
  function callback($buffer)
  {
        return preg_replace('/<!--(.|\s)*?-->/', '', $buffer);
  }

  ob_start("callback");
?>
... HTML source goes here ...
<?php ob_end_flush(); ?>
Run Code Online (Sandbox Code Playgroud)

由于我的正则表达式不是太热,我无法弄清楚如何修改模式以排除条件注释,例如:

<!--[if !IE]><!-->
<link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen" />
<!-- <![endif]-->

<!--[if IE 7]>
<link rel="stylesheet" href="/css/ie7.css" type="text/css" media="screen" />
<![endif]-->

<!--[if IE 6]>
<link rel="stylesheet" href="/css/ie6.css" type="text/css" media="screen" />
<![endif]-->
Run Code Online (Sandbox Code Playgroud)

干杯

Tom*_*lak 23

由于注释不能嵌套在HTML中,因此正则表达式可以在理论上完成这项工作.尽管如此,使用某种解析器将是更好的选择,特别是如果您的输入不能保证格式良好.

这是我的尝试.要仅匹配正常注释,这将起作用.它已成为一个巨大的怪物,对不起.我已经对它进行了相当广泛的测试,它似乎做得很好,但我不保证.

<!--(?!\s*(?:\[if [^\]]+]|<!|>))(?:(?!-->).)*-->
Run Code Online (Sandbox Code Playgroud)

说明:

<!--                #01: "<!--"
(?!                 #02: look-ahead: a position not followed by:
  \s*               #03:   any number of space
  (?:               #04:   non-capturing group, any of:
    \[if [^\]]+]    #05:     "[if ...]"
    |<!             #06:     or "<!"
    |>              #07:     or ">"
  )                 #08:   end non-capturing group
)                   #09: end look-ahead
(?:                 #10: non-capturing group:
  (?!-->)           #11:   a position not followed by "-->"
  .                 #12:   eat the following char, it's part of the comment
)*                  #13: end non-capturing group, repeat
-->                 #14: "-->"
Run Code Online (Sandbox Code Playgroud)

步骤#02和#11至关重要.#02确保以下字符不表示条件注释.之后,#11确保以下字符不表示注释的结束,而#12和#13引起实际匹配.

使用"global"和"dotall"标志.

要做相反的事情(仅匹配条件注释),它将是这样的:

<!(--)?(?=\[)(?:(?!<!\[endif\]\1>).)*<!\[endif\]\1>
Run Code Online (Sandbox Code Playgroud)

说明:

<!                  #01: "<!"
(--)?               #02: two dashes, optional
(?=\[)              #03: a position followed by "["
(?:                 #04: non-capturing group:
  (?!               #05:   a position not followed by
    <!\[endif\]\1>  #06:     "<![endif]>" or "<![endif]-->" (depends on #02)
  )                 #07:   end of look-ahead
  .                 #08:   eat the following char, it's part of the comment
)*                  #09: end of non-capturing group, repeat
<!\[endif\]\1>      #10: "<![endif]>" or "<![endif]-->" (depends on #02)
Run Code Online (Sandbox Code Playgroud)

再次,使用"global"和"dotall"标志.

步骤#02是因为"downlevel-revealed"语法,请参阅:"MSDN - 关于条件注释".

我不完全确定允许或预期的空间.\s*在适当的地方添加到表达式.