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


149

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

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

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

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

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


18
面白い問題ですが、本物です。私は投票します。
Voitcus 2013年

17
ああ、神様。最初、私はあなたの質問に懐疑的で、何が問題なのかを尋ねる準備ができていましたが、次に '?これはphpsadness.com
lolesque

6
このような「機能」の有用性は、php.net/manual/en/language.basic-syntax.comments.phpで説明されています。これは、ワンライナーの場合に役立ち<?php # echo 'simple';?>ます。
ロレスク2013年

2
@lolesqueそのリンクをありがとう。いいもの。他の言語もカバーする関連するもの:wiki.theory.org/YourLanguageSucks
Simon Forsberg

5
@OndraŽižkaは、繰り返し行われているbrタグを削除するだけです。正規表現はそのためにうまく動作します。悪いからといって、常に悪いというわけではありません。
2013年

回答:


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);

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


@ppeterkaうわー、私はそれについてさえ考えていませんでした。ありがとうございました。
v1n_vampire 2013年

1
私は2日前にCでこのトリックを使用しなければなりませんでした??<
Ryan Amos

2
偉大な者。なぜそんなふうに思わないの!?
サン

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 修飾子 -別名PCRE_EXTENDED- (彼らは文字クラス内部で発生する場合を除く)正規表現での無視空白と改行。これにより、問題のある文字を区切るためにスペースを追加することができます。両方のコメントスタイルを修正するには:

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

@Cthulhu +1(そしてもちろん答えも)。また、(少なくとも私にとっては)これは正規表現を理解するのを少し難しくします。それほどではありませんが、この正規表現を見た場合、次のように言います。うーん、どうなっているのですか。しかし、それは実に完全に主観的です。
ppeterka 2013年

1
私が使用して、別の方法を発見したので@ppeterka私は多少、同意x修飾子を:)
ジャック

@ジャックニース、もう1つ+1をします。新しいことを学びました...正規表現の修飾子を忘れてしまいます(私はそれ以外に使用することはめったにありませんg)...
ppeterka

@ジャックありがとう、私はソリューションから正規表現について新しいことを学びます。
v1n_vampire 2013年

1
正規表現を前の行に分離するための+1。正規表現は同じままですが、ロジックをコメント化することができます。

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


まだわからないことがたくさんあります...参考になります。
v1n_vampire 2013年

4
この投稿は、はるかに多くの+1に値するでしょう...完全な説明だけのために。
ppeterka 2013年

15

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

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

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


@ppeterka:私は文字クラスの代わりにバックスラッシュを使用しました(しかし、はい、1回発生しませんでした。ありがとう!)
Tim Pietzcker

申し訳ありませんが、私は疲れているようです... []に囲まれてそこに残された2番目のものに気づきました...
ppeterka

10

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

? 便宜上、数量化のショートカットにすぎません。

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

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

1
+1このページは、私たちの心の奥に留めておくための正規表現のトリックを収集するための非常に良い場所になり始めています。
ppeterka 2013年

1
@ppeterka、私は実際には他のすべての答えを「トリック」と呼んでいますが、私の答えは、数量詞の長いバージョンを使用していて、ショートカットではありません。
Stea 2013年

3
私の辞書ではそれだけで問題ありません。短くて便利な構文シュガーの代わりに、長いバージョンの式を使用することもトリックとして数えられます...
ppeterka

8

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

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

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

  • 所有的な量指定子を使用する#(<br\s*+/?+>)+#i-基本的に\s*+、空白と一致/?+するものが見つかった場合はそれを維持し、スラッシュを発見した場合は維持します。
  • 囲み\s*および/*キャプチャグループで=>#(<br(\s*)(/?)>)+#i

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

そして、私たちは所有的行動を傾けたので、コメントの問題も回避する最速のRegExは次のとおりです。デモの説明#(<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はに似ているヒアドキュメントが、それは、コンテンツを解析し、それがだ持っている必要がありません開始に囲まれた区切り文字'の単一引用符'ことに注意してください終了区切り文字はidentedすることができない、続かなければなりません;し、新しい行を

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.