2024 年 PHP 日本大会

子模式

子模式由括号(圆括号)分隔,可以嵌套。将模式的一部分标记为子模式有两个作用

  1. 它限定了一组备选方案。例如,模式 cat(aract|erpillar|) 匹配“cat”、“cataract”或“caterpillar”中的一个单词。如果没有括号,它将匹配“cataract”、“erpillar”或空字符串。

  2. 它将子模式设置为捕获子模式(如上所定义)。当整个模式匹配时,匹配子模式的主题字符串部分将通过 pcre_exec()ovector 参数传递回调用方。从左到右(从 1 开始)对左括号进行计数,以获得捕获子模式的编号。

例如,如果字符串“the red king”与模式 the ((red|white) (king|queen)) 匹配,则捕获的子字符串为“red king”、“red”和“king”,编号分别为 1、2 和 3。

普通括号同时执行两个功能并非总是方便的。通常情况下,需要一个分组子模式而不需要捕获要求。如果左括号后跟“?:”,则子模式不执行任何捕获,并且在计算任何后续捕获子模式的数量时不予计数。例如,如果字符串“the white queen”与模式 the ((?:red|white) (king|queen)) 匹配,则捕获的子字符串为“white queen”和“queen”,编号分别为 1 和 2。捕获子字符串的最大数量为 65535。但是,根据 libpcre 的配置选项,可能无法编译这么大的模式。

作为一个方便的简写,如果在非捕获子模式的开头需要任何选项设置,则选项字母可以出现在“?”和“:”之间。因此,这两个模式

(?i:saturday|sunday)
(?:(?i)saturday|sunday)

匹配完全相同的字符串集。因为备选分支是从左到右尝试的,并且选项直到子模式结束才会重置,所以一个分支中的选项设置会影响后续的分支,因此上述模式匹配“SUNDAY”以及“Saturday”。

可以使用语法 (?P<name>pattern) 为子模式命名。然后,此子模式将在匹配数组中按其正常的数字位置和名称进行索引。还有两种替代语法 (?<name>pattern)(?'name'pattern)

有时需要在正则表达式中进行多次匹配,但子组交替出现。通常情况下,即使这些子组中只有一个可能匹配,每个子组都会被赋予自己的反向引用编号。为了克服这个问题,(?| 语法允许使用重复的编号。考虑以下与字符串 Sunday 匹配的正则表达式

(?:(Sat)ur|(Sun))day

这里 Sun 存储在反向引用 2 中,而反向引用 1 为空。匹配 Saturday 会在反向引用 1 中产生 Sat,而反向引用 2 不存在。将模式更改为使用 (?| 可以解决此问题

(?|(Sat)ur|(Sun))day

使用此模式,SunSat 都将存储在反向引用 1 中。

添加注释

用户贡献的注释

此页面没有用户贡献的注释。
To Top