0

2つの中括弧内の文字の最初の出現に一致させたいのですが、その中の文字は無視します。

{{some text here {{nested text here}} another text {{another nested text here}} final text}}

したがって、結果は次のようになります。

some text here {{nested text here}} another text {{another nested text here}} final text

しかし、この検索

preg_match_all("^\{{(.*?)\}}^", $string, $results);

角かっこの最初のペアの内側にあるものを教えてください。

$results[0][0] = nested text here
$results[0][1] = another nested text here

preg_match_allでこれを達成する方法はありますか?

4

1 に答える 1

3

ネストされた構造は、正規表現で問題を引き起こすことがよくあります(これは、言語の照合が通常よりも複雑になるためです)。PCREは、再帰をサポートしているため、それらのマッチングを可能にするエンジンの1つです。ダブルブラケット内にシングルカーリーブラケットがない場合は、次のパターンを使用できます。

'/\{\{[^{}]*(?:(?R)[^{}]*)*\}\}/'

(?R)パターン全体を再びネストする場所。

PCREがどれだけうまく最適化されるかはわかりませんが、すべての繰り返しを所有格にすることで、少し役立つことがあります。これにより、バックトラックが抑制されます。これは、連続するすべての繰り返しが相互に排他的であるため、ここでは必要ありません。

'/\{\{[^{}]*+(?:(?R)[^{}]*+)*+ \}\}/'

単一の角かっこを許可する場合は、先読みで同様のことを行うことができますが、これは、(エンジンがサポートしている場合でも)ネストされた構造に対して正規表現が実際に作成されない理由をすでに示しています。

'/\{\{(?:(?!\{\{|\}\}).)*(?:(?R)(?:(?!\{\{|\}\}).)*)*\}\}/'

これで、文字以外の代わりに、または{}の先頭をマークしない限り、任意の文字の繰り返しを許可します。繰り返しますが、所有格にするのは良い考えかもしれません:{{}}

'/\{\{(?:(?!\{\{|\}\}).)*+(?:(?R)(?:(?!\{\{|\}\}).)*+)*+\}\}/'
于 2012-12-02T23:12:56.033 に答える