使用PHP剥离HTML注释,但保留条件

使用PHP剥离HTML注释,但保留条件,php,regex,comments,conditional,strip,Php,Regex,Comments,Conditional,Strip,我目前正在使用PHP和正则表达式从页面中删除所有HTML注释。剧本很好。。。有点太好了。它将删除所有注释,包括我在中的条件注释。以下是我得到的: <?php function callback($buffer) { return preg_replace('/<!--(.|\s)*?-->/', '', $buffer); } ob_start("callback"); ?> ... HTML source goes here ... &

我目前正在使用PHP和正则表达式从页面中删除所有HTML注释。剧本很好。。。有点太好了。它将删除所有注释,包括我在中的条件注释。以下是我得到的:

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

  ob_start("callback");
?>
... HTML source goes here ...
<?php ob_end_flush(); ?>

... HTML源代码在这里。。。
因为我的正则表达式不是很热,所以我很难找出如何修改模式以排除条件注释,例如:

<!--[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]-->


干杯

像这样的事情可能有用:

/<!--[^\[](.|\s)*?-->/
//

它与您的相同,只是它忽略注释,在注释开始标记后面有一个开始括号。

我不确定PHP的正则表达式引擎是否会喜欢以下内容,但请尝试以下模式:

'/<!--(.|\s)*(\[if .*\]){0}(.|\s)*?-->/'
'/'

如果您无法让它与一个正则表达式一起工作,或者您发现您想要保留更多可以使用的注释。然后可以定义一个函数来单独处理注释

<?php
function callback($buffer) {
    return preg_replace_callback('/<!--.*-->/U', 'comment_replace_func', $buffer);
}

function comment_replace_func($m) {
    if (preg_match( '/^\<\!--\[if \!/i', $m[0])) {
        return $m[0];   
    }              

    return '';
}   

ob_start("callback");
?>

... HTML source goes here ...

<?php ob_end_flush(); ?>

... HTML源代码在这里。。。

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

这是我的尝试。为了只匹配正常的注释,这是可行的。很抱歉,它已经变成一个怪物了。我已经对它进行了广泛的测试,它似乎做得很好,但我不提供任何保证

)*-->
说明:

)#11:后面不跟“->”的位置
.                 #12:吃下下面的炭,这是评论的一部分
)*#13:结束非捕获组,重复
-->                 #14: "-->"
第02步和第11步至关重要#02确保以下字符不表示条件注释。之后,#11确保以下字符不表示注释的结尾,而#12和#13导致实际匹配

使用“全局”和“dotall”标志应用

要执行相反的操作(仅匹配条件注释),应该如下所示:

))*
说明:

#06:“或”(取决于#02)
)#07:展望的结束
.                 #08:吃下下面的炭,这是评论的一部分
)*#09:非捕获组结束,重复
#10:“或”(取决于#02)
同样,使用“全局”和“dotall”标志应用

步骤#02是因为使用了“downlever”语法,请参见:


我不完全确定空间是允许的还是应该的。在适当的地方将
\s*
添加到表达式中。

总之,这似乎是最好的解决方案:

<?php
  function callback($buffer) {
    return preg_replace('/<!--[^\[](.|\s)*?-->/', '', $buffer);
  }
  ob_start("callback");
?>
... HTML source goes here ...
<?php ob_end_flush(); ?>

... HTML源代码在这里。。。
它去掉所有注释并留下条件句,但最上面的注释除外:

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

这些额外的问题似乎导致了问题

如果有人能建议将这一点考虑在内的正则表达式,并将该条件保留在适当的位置,那么这将是完美的

Tomalak的解决方案看起来不错,但作为一个新手,没有进一步的指导方针,我不知道如何实现它,尽管我想尝试一下,如果有人能详细说明如何应用它


谢谢

你好,博登。这个方法删除了注释,但留下了注释,这意味着没有应用样式表,文档中到处都是箭头。您这样称呼它吗?(不确定此代码是否会在注释中发布)preg_replace(“//”,“$buffer”);是,整行:返回preg_replace('/','$buffer);这不会留下括号,但也不会成功地留下条件注释:嗯。。。我在这里运行它:使用preg_replace选项,我剪切并粘贴了您的代码片段:它将条件保留在那里。听起来确实很奇怪。我刚刚复制并粘贴了您的代码,并再次尝试,但同样的事情仍在发生。我的条件注释与我的原始问题中的注释完全相同,但仍保留在上面的注释中。用此替换我的正则表达式将提示index.php页面的下载保存弹出窗口,而不是呈现它。我认为脚本应该像这样插入头部,对吗:。。。HTML源代码在这里。。。如果是这样,这不会删除任何评论或似乎有任何影响?嗨,Tomalak,感谢您的输入和详细解释。使正则表达式更容易:)。然而,我刚刚尝试了你的解决方案,它除了一个空白页面之外,什么都不显示。我使用的完整行是:return preg_replace(')*-->','$buffer);这是正确的吗?我必须承认我以前没有遇到过preg_replace,所以一旦有机会,我会尽快阅读文档。然而,对于这个特殊问题,您是否可以详细阐述一下如何实现它?虽然它看起来比正则表达式更广泛,但听起来像是一种有趣的方法,我想尝试一下。你现在有机会阅读文档:)(也:)尝试了很多其他正则表达式,但这是一个最终的方法,它按照我的要求工作。