2

パターンを持つ preg_match_all 関数があります。

preg_match_all(
    '/\[(if) ([^\]]*)\]
    ((?:(?!\[if).|(?R))*?)
    \[endif\]/sx',
    $text,
    $matches
);

これは非常に簡単なパターンだと思いますが、構文を探します[if condition] sometext [endif]が、埋め込み ifs fe もサポートしています[if condition1] aa [if condition2] bb [endif] [endif]。s スイッチを使用して改行をドットとして扱い (複数行で動作させたいため)、読みやすくするために x を使用しました (ただし、x を削除しても問題は解決しません)。

私が持っているほとんどの入力データでは正常に機能しますが、特定の入力では、ログにエラーや例外がなくても、nginx サーバーで 502 Bad gateway エラーが発生します。nginx + php-fpm (5.6.15-1+deb.sury.org~trusty+1) を使用していますが、php7 でも同じことが起こります。

これは、変数と正規表現だけの非常に単純な、簡単に確認できる PHP コードです。

http://pastebin.com/G54Xa0as

すべてのスペース、タブなどを含めて、コンテンツを 1:1 でコピーしたことを確認してください。

非常に奇妙なことは、ほとんどすべての単一行を削除したり、1 つのインデント (任意の場所にあるいくつかのスペース) を削除したりして、機能させることができることです。

ここで何が問題なのかわかりません。問題を示すためにこの単一のファイルを作成できましたが、修正方法はわかりません。

4

1 に答える 1

2

正規表現には、ドット パターンを「調整」する否定的な先読みが含まれています。ただし、終了区切り文字を追加できなかったため、かなり「重い」ものになりました。

[endif]先読みチェックに終了区切り文字 ( ) を追加することをお勧めします。

\[(if)\s+([^\]]*+)\]((?>(?!\[(?:end)?if\b).|(?R))*)\[endif\]
                             ^^^^^^^^

デモを見る

または、強化された貪欲なトークンを次のようにアンロールすることもできます。

\[(if)\s+([^\]]*+)\]((?>[^[]++(?:\[(?!(?:end)?if\b)[^[]*)*|(?R))*)\[endif\]

正規表現のデモを参照してください(ただし、 a[が続く場合[if...]は機能しません)。

また、正規表現の後にスペースがあり、修飾子を使用しているため、リテラル スペースとは見なされず、無視されることに注意してください。そのため、 に変更しました。(if)/x\s+

于 2016-05-26T12:01:56.217 に答える