152

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

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

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

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

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

4

6 に答える 6

124

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

あなたのコードでは:

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

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

/* */コメントを機能させるには、シーケンスも分割する必要があります*/

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

時々、全体がその部分の合計よりも多いとしても、貪欲であることは悪いことですが、より少ないものを残したほうがよい場合があることを覚えておいてください。:)

于 2013-03-05T09:13:07.773 に答える
73

最も簡単な方法

正規表現を保持するための別の変数を作成します。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);
                               ^ ^              ^ ^

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

/x修飾子の使用を修正

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

$string = preg_replace('#<br\s* /? >(?:\s*<br\s* /? >)+#ix', '<br />', $string);
                               ^  ^             ^  ^
于 2013-03-05T09:16:18.923 に答える
38

あなたの試みがうまくいかなかった理由:

// $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モードに戻り、//または#はそれに影響を与えることができません。

于 2013-03-05T09:31:39.210 に答える
15

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

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

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

于 2013-03-05T17:34:15.957 に答える
10

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

?便宜上の数量詞のショートカットにすぎないので、

数量詞の長いバージョンを使用するだけで、{0,1}「最小0最大1回」を意味します。

$string = preg_replace('#<br\s*/{0,1}>(?:\s*<br\s*/{0,1}>)+#i', '<br />', $string);
于 2013-03-07T06:04:35.667 に答える
8

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

/(<br\s*/?>)+/iまず、RegExを次のように圧縮して次のように置き換えることができます<br />(RegExPに先読みを付ける必要はありません)。そうすると、選択したXHMTL改行が常に発生します。

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

  • 所有格の数量詞を使用します:#(<br\s*+/?+>)+#i-これは基本的に、\s*+空白ができるだけ多く一致していることを見つけてそれを保持し/?+、スラッシュを見つけた場合はそれを保持することを意味します!
  • 囲み\s*/*キャプチャグループに=>#(<br(\s*)(/?)>)+#i

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

そして、所有格の振る舞いを学習したので、コメントの問題もバイパスする最速の正規表現は次のとおりです#(<br\s*+/?+>)++#i


トリッキーな状況でのコメントについて

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

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

注:nowdocはヒアドキュメントに似ていますが、コンテンツを解析せず、開始区切り文字を'一重引用符で囲む必要があり'ます(終了区切り文字は識別できないため、後に改行を追加する必要があります!;

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

于 2013-04-10T05:19:18.350 に答える