这是一个匹配双花括号内的内容的模式:
$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 语法中,但\\\
或\\\\
在单引号内。
详细模式说明:
该模式分为两部分:
定义部分有助于避免在主模式中多次重复相同的子模式或使其更清晰。您可以定义稍后将在此空间中使用的子模式:
(?(DEFINE)....)
本节包含 2 个命名子模式:
- 引用:包含引用部分的描述
- 嵌套:描述嵌套的大括号部分
嵌套细节
(?<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
我使用 to 修饰符x
和s
. x
激活详细模式,允许在模式中自由放置空格(用于缩进)。s
是单行模式。在这种模式下,点可以匹配换行符(默认情况下不能)。我使用这种模式是因为 subpattern 中有一个点quoted
。