0

我正在写一个评论剥离器,并试图在这里满足所有需求。我有下面的代码堆栈,它删除了几乎所有的评论,但它实际上走得太远了。很多时间都花在了尝试、测试和研究匹配的正则表达式模式上,但我并不认为它们在每个方面都是最好的。

我的问题是,我也有“PHP 注释”(在标准代码甚至 PHP 字符串中并不是真正的注释)的情况,我实际上并不想删除这些注释。

例子:

<?php $Var = "Blah blah //this must not comment"; // this must comment. ?>

最终发生的事情是它虔诚地剥离,这很好,但它留下了某些问题:

<?php  $Var = "Blah blah  ?>

还:

也会导致问题,因为注释删除了该行的其余部分,包括结尾?>

看到问题了吗?所以这就是我需要的...

  • '' 或 "" 中的注释字符需要忽略
  • 同一行中使用双斜杠的 PHP 注释应该只删除注释本身,或者应该删除整个 php 代码块。

这是我目前使用的模式,请随时告诉我是否可以对现有模式进行改进?:)

$CompressedData = $OriginalData;
$CompressedData = preg_replace('!/\*.*?\*/!s', '', $CompressedData);  // removes /* comments */
$CompressedData = preg_replace('!//.*?\n!', '', $CompressedData); // removes //comments
$CompressedData = preg_replace('!#.*?\n!', '', $CompressedData); // removes # comments
$CompressedData = preg_replace('/<!--(.*?)-->/', '', $CompressedData); // removes HTML comments

您能给我的任何帮助将不胜感激!:)

4

4 回答 4

4

如果要解析 PHP,可以使用token_get_all来获取给定 PHP 代码的令牌。然后你只需要迭代标记,删除评论标记并将其余的重新组合在一起。

但是您需要一个单独的程序来处理 HTML 注释,最好也是一个真正的解析器(就像DOMDocument提供的一样DOMDocument::loadHTML)。

于 2010-03-19T08:51:45.803 回答
3

您应该首先仔细考虑您是否真的要这样做。尽管您正在做的事情看起来很简单,但在最坏的情况下,它会变成极其复杂的问题(只需几个正则表达式即可解决)。让我仅举例说明在尝试从文件中去除 HTML 和 PHP 注释时您将面临的几个问题。

您不能直接去除 HTML 注释,因为 HTML 注释中可能包含 PHP,例如:

<!-- HTML comment <?php echo 'Actual PHP'; ?> -->

您也不能简单地单独处理<?phpand?>标记中的内容,因为结尾 thag?>可以在字符串甚至注释中,例如:

<?php /* ?> This is still a PHP comment <?php */ ?>

我们不要忘记,?>如果它前面有一行注释,它实际上结束了 PHP。例如:

<?php // ?> This is not a PHP comment <?php ?>

当然,就像您已经说明的那样,字符串中的注释指示符会有很多问题。解析字符串以忽略它们也不是那么简单,因为您必须记住引号可以被转义。喜欢:

<?php
$foo = ' /* // None of these start a comment ';
$bar = ' \' // Remember escaped quotes ';
$orz = " ' \" \' /* // Still not a comment ";
?>

解析顺序也会让你头疼。您不能简单地选择先解析单行注释或先解析多行注释。它们都必须同时被解析(即按照它们在文档中出现的顺序)。否则你可能会得到损坏的代码。让我举例说明:

<?php
/* // Multiline comment */
// /* Single Line comment
$omg = 'This is not in a comment */';
?>

如果您首先解析多行注释,则第二个 /* 将占用部分字符串,从而破坏代码。如果你先解析单行注释,你最终会吃掉第一个 */,这也会破坏代码。

如您所见,如果您打算使用正则表达式解决问题,则必须考虑许多复杂的场景。唯一正确的解决方案是使用某种 PHP 解析器,例如token_get_all(),对整个源代码进行标记,并去除注释标记并重建文件。恐怕这也不完全简单。它也对 HTML 注释没有帮助,因为 HTML 没有被触及。您也不能使用 XML 解析器来获取 HTML 注释,因为 HTML 很少用 PHP 形成良好的格式。

简而言之,您正在做的事情的想法很简单,但实际实现比看起来要困难得多。因此,我建议尽量避免这样做,除非你有充分的理由这样做。

于 2010-03-19T10:58:15.350 回答
0

在 REGEX 中执行此操作的一种方法是使用一个复合表达式和preg_replace_callback.

我打算发布一个糟糕的例子,但最好的地方是查看 Dean Edwards 的 JS 打包脚本的 PHP 端口的源代码 - 你应该看到一般的想法。

http://joliclic.free.fr/php/javascript-packer/en/

于 2010-03-19T10:05:51.967 回答
-1

尝试这个

private function removeComments( $content ){
    $content = preg_replace( "!/\*.*?\*/!s" , '', $content );
    $content = preg_replace( "/\n\s*\n/" , "\n", $content );    
    $content = preg_replace( '#^\s*//.+$#m' , "", $content );
    $content = preg_replace( '![\s\t]//.*?\n!' , "\n", $content );
    $content = preg_replace( '/<\!--.*-->/' , "\n", $content );
    return $content;
}
于 2017-10-06T19:13:51.040 回答