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を解析する場合は、を使用して特定のPHPコードのトークンtoken_get_allを取得できます。次に、トークンを繰り返し、コメントトークンを削除して、残りを元に戻す必要があります。

ただし、HTMLコメント用に別の手順が必要になります。できれば実際のパーサーも必要です(DOMDocumentが提供するようにDOMDocument::loadHTML)。

于 2010-03-19T08:51:45.803 に答える
3

本当にこれをやりたいのかどうか、最初によく考えてください。あなたがやっていることは単純に見えるかもしれませんが、最悪の場合、非常に複雑な問題になります (わずかな正規表現で解決する必要があります)。ファイルから HTML と PHP の両方のコメントを取り除こうとするときに直面するであろういくつかの問題の例をいくつか挙げてみましょう。

次のように、HTML コメント内に PHP が含まれている可能性があるため、HTML コメントを直接削除することはできません。

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

次のように、終了タグが文字列またはコメント内にある可能性があるため<?php、タグ内のものを単純に個別に処理することはできません。?>?>

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

?>1 行のコメントが前にある場合、実際には 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 ";
?>

解析順序も頭痛の種になります。最初に 1 行のコメントを解析するか、最初に複数行のコメントを解析するかを単純に選択することはできません。両方を同時に解析する必要があります (つまり、ドキュメントに表示される順序で)。そうしないと、コードが壊れてしまう可能性があります。説明しましょう:

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

最初に複数行のコメントを解析すると、2 番目の /* によって文字列の一部が消費され、コードが破壊されます。最初に 1 行のコメントを解析すると、最初の */ を食べてしまい、コードも破壊されます。

ご覧のとおり、正規表現で問題を解決しようとする場合、考慮しなければならない複雑なシナリオが多数あります。唯一の正しい解決策は、 などの PHP パーサーを使用してtoken_get_all()ソース コード全体をトークン化し、コメント トークンを削除してファイルを再構築することです。残念ながら、これも完全に単純ではありません。また、HTML はそのままであるため、HTML コメントにも役立ちません。XML パーサーを使用して HTML コメントを取得することもできません。これは、HTML が PHP で適切に形成されることはめったにないためです。

簡単に言うと、やっていることのアイデアは単純ですが、実際の実装は見た目よりもはるかに困難です。したがって、よほどの理由がない限り、これを避けることをお勧めします。

于 2010-03-19T10:58:15.350 に答える
0

REGEX でこれを行う 1 つの方法は、1 つの複合式 and を使用すること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 に答える