これは、二重中かっこ内のコンテンツに一致するパターンです。
$pattern = <<<'LOD'
~
(?(DEFINE)
(?<quoted>
' (?: [^'\\]+ | (?:\\.)+ )++ ' |
" (?: [^"\\]+ | (?:\\.)+ )++ "
)
(?<nested>
{ (?: [^"'{}]+ | \g<quoted> | \g<nested> )*+ }
)
)
{{
(?<content>
(?:
[^"'{}]+
| \g<quoted>
| \g<nested>
)*+
)
}}
~xs
LOD;
コンパクトバージョン:
$pattern = '~{{((?>[^"\'{}]+|((["\'])(?:[^"\'\\\]+|(?:\\.)+|(?:(?!\3)["\'])+)++\3)|({(?:[^"\'{}]+|\g<2>|(?4))*+}))*+)}}~s';
コンテンツは最初のキャプチャ グループにありますが、名前付きキャプチャ'content'
を詳細バージョンで使用できます。
このパターンが長い場合、エスケープされた引用符を含む、引用符で囲まれた部分の内部で必要なものがすべて許可され、多くの場合、単純な遅延量指定子よりも高速になります。ネストされた中括弧も許可されており、{{ doThat(){ doThis(){ }}}}
問題なく記述できます。
引用符のサブパターンもこのように書くことができ、一重引用符と二重引用符で同じことを繰り返さないようにします (コンパクト バージョンで使用します)。
(["']) # the quote type is captured (single or double)
(?: # open a group (for the various alternatives)
[^"'\\]+ # all characters that are not a quote or a backslash
| # OR
(?:\\.)+ # escaped characters (with the \s modifier)
| #
(?!\g{-1})["'] # a quote that is not the captured quote
)++ # repeat one or more times
\g{-1} # the captured quote (-1 refers to the last capturing group)
注意: バックスラッシュ\\
は nowdoc 構文で記述する必要がありますが\\\
、\\\\
単一引用符で囲む必要があります。
詳細なパターンの説明:
パターンは次の 2 つの部分に分かれています。
- 名前付きサブパターンを定義する定義
- 全体のパターン自体
定義セクションは、メイン パターンで常に同じサブパターンを何度も繰り返すことを避けたり、より明確にしたりするのに役立ちます。このスペースで後で使用するサブパターンを定義できます。
(?(DEFINE)....)
このセクションには、2 つの名前付きサブパターンが含まれています。
- quoted : 引用部分の説明を含む
- nested : ネストされた中括弧部分を記述します
入れ子の詳細
(?<nested> # open the named group "nested"
{ # literal {
## what can contain curly brackets? ##
(?> # open an atomic* group
[^"'{}]+ # all characters one or more times, except "'{}
| # OR
\g<quoted> # quoted content, to avoid curly brackets inside quoted parts
# (I call the subpattern I have defined before, instead of rewrite all)
| \g<nested> # OR curly parts. This is a recursion
)*+ # repeat the atomic group zero or more times (possessive *)
} # literal }
) # close the named group
(*原子団と所有量指定子に関する詳細情報)
しかし、これはすべて定義にすぎません。パターンは実際には次のように始まります。{{
次に、名前付きのキャプチャ グループ ( content
) を開き、内部にあるものを記述します (ここには新しいものはありません)。
私は修飾子に使用しx
、s
. x
パターンに自由にスペースを入れることができる冗長モードを有効にします (インデントに便利です)。s
シングルラインモードです。このモードでは、ドットは改行に一致します (デフォルトでは一致しません)。サブパターンにドットがあるため、このモードを使用しますquoted
。