web-dev-qa-db-ja.com

PHPタグをコメントに変換する

スクリプトの行の1つにPHP文字列内の終了タグが含まれています。通常の操作ではこれは問題になりませんが、行をコメント化する必要があります。

///**/、および#でこの行をコメントアウトしようとしましたが、いずれも機能しません。パーサーは終了タグを実際の終了タグと見なします。

問題の行は次のとおりです。

$string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i', '<br />', $string);
//                              ^^             ^^

上記の行をコメントアウトするにはどうすればよいですか?

150
v1n_vampire

トリックを使用:2つの部分から文字列を連結します。この方法では、終了タグは2つに分割され、有効な終了タグではなくなります。 '?>' --> '?'.'>'

あなたのコードで:

$string = preg_replace('#<br\s*/?'.'>(?:\s*<br\s*/?'.'>)+#i', '<br />', $string);

これにより、//コメントは機能します。

にとって /* */コメントを機能させるには、*/シーケンスも:

$string = preg_replace('#<br\s*'.'/?'.'>(?:\s*<br\s*'.'/?'.'>)+#i', '<br />', $string);

時々、全体がその部分の合計よりもmoreであっても-貪欲であることは悪いことですが、lessを残した方が良い場合があることを覚えておいてください。 :)

125
ppeterka

最も簡単な方法

正規表現を保持する別の変数を作成します。この方法で、単にpreg_replace()ステートメントをコメントアウトできます:

$re = '#<br\s*/?>(?:\s*<br\s*/?>)+#i';
// $string = preg_replace($re, '<br />', $string);

文字クラスを使用して修正する

行コメントを修正するには、次のように?>を文字クラス内に配置して、>を分割できます。

$string = preg_replace('#<br\s*/?[>](?:\s*<br\s*/?[>])+#i', '<br />', $string);
                                 ^ ^              ^ ^

ブロックコメントを修正するには、/に適用できます:

$string = preg_replace('#<br\s*[/]?>(?:\s*<br\s*[/]?>)+#i', '<br />', $string);
                               ^ ^              ^ ^

両方のコメントスタイルを修正するには、/and>を独自の文字クラスに入れることができます。

/x修飾子を使用して修正する

x修飾子​​ -別名PCRE_EXTENDED-正規表現内のスペースと改行を無視します(文字クラス内で発生する場合を除く)。これにより、スペースを追加して問題のある文字を区切ることができます。両方のコメントスタイルを修正するには:

$string = preg_replace('#<br\s* /? >(?:\s*<br\s* /? >)+#ix', '<br />', $string);
                               ^  ^             ^  ^
74
Ja͢ck

試行が機能しなかった理由:

// $string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i',...
                                   ^ doesn't work due to ?> ending php

/* $string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i',... */
                                 ^ doesn't work due to */ closing comment

動作:

/* $string = preg_replace('#<br\s*[/]?>(?:\s*<br\s*[/]?>)+#i',... */
                                  ^ ^              ^ ^
// $string = preg_replace('#<br\s*/?[>](?:\s*<br\s*/?[>])+#i',...
                                    ^ ^              ^ ^

さらに...

上記の後、/*を使用して行をコメントアウトできるはずです。 ?>をそのままにすると、//は行全体をコメントアウトできなくなります。 ?>に続くテキストはhtmlである可能性があり、これはPHPインタープリターのコントロール外であるため、機能しません。

ドキュメント:から

「1行」のコメントスタイルは、行末またはPHPコードのどちらか早い方)にのみコメントします。これは// ...?>の後のHTMLコードを意味しますまたは#...?>が出力されます:?>はPHPモードから抜け出し、HTMLモードに戻ります。///または#はそれに影響を与えることはできません。

39

別のアイデア:>(および/コメントを使用する場合は/*...*/をエスケープします):

$string = preg_replace('#<br\s*\/?\>(?:\s*<br\s*\/?\>)+#i', '<br />', $string);

「不必要な」エスケープは正規表現エンジンによって無視されますが、この場合は便利です(他の回答で概説されている理由のため)。

16
Tim Pietzcker

なぜ複雑で読みにくい「トリック」を使用して問題を回避するのですか?

?は、便宜上の量指定子のショートカットにすぎないため、

量指定子の長いバージョンを使用する{0,1}は、「最小0最大1回」を意味します。

$string = preg_replace('#<br\s*/{0,1}>(?:\s*<br\s*/{0,1}>)+#i', '<br />', $string);
11
stema

RegExトリックブックに追加する価値のある他のいくつかの方法:

まず、RegExを/(<br\s*/?>)+/iに圧縮し、<br />(RegExPに先読みを負担する必要はありません)に置き換えると、常に選択したXHMTL改行で終わる可能性があります。

*/終了コメントまたは?>終了スクリプトをトリップしないようにRegExを変更する他の方法:

  • possessive quantifiers#(<br\s*+/?+>)+#iを使用します。これは基本的に、\s*+が存在する場合はそれと同じ数の空白が見つかった場合に意味し、スラッシュが見つかった場合は/?+を意味します。
  • \s*/*をキャプチャグループで囲む=> #(<br(\s*)(/?)>)+#i

ライブデモ: http://codepad.viper-7.com/YjqUbi

そして、私たちが所有的な振る舞いを学習したので、コメントの問題も回避する最も速いRegExは次のとおりです。#(<br\s*+/?+>)++#iexplained demo


トリッキーな状況でのコメントに関して

コードを変更できない場合、またはすでに複数行のコメントを使用している場合:

1. nowdocを使用します。

    $string='Hello<br>World<br><br />World<br><br><br>Word!';
    <<<'comment'
    $string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string);
comment;

ライブコード: http://codepad.viper-7.com/22uOtV

注:nowdocheredocに似ていますが、コンテンツを解析せず、'singleで囲まれたstartingデリミタが必要です。 quotes'終了デリミタは識別できませんに注意してください。その後に;new lineが続く必要があります)

2. goto でコードを飛び越えます:

$string='Hello<br>World<br><br />World<br><br><br>Word!';
goto landing;
$string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string);
landing:

ライブの例: http://codepad.viper-7.com/UfqrIQ

3. if(false)またはif(0)でコードを飛び越えます:

$string='Hello<br>World<br><br />World<br><br><br>Word!';
if(0){
$string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string);
}

テスト: http://codepad.viper-7.com/wDg5H5

9
CSᵠ