子模式由括号(圆括号)分隔,可以嵌套。将模式的一部分标记为子模式有两个作用
它限定了一组备选方案。例如,模式 cat(aract|erpillar|)
匹配“cat”、“cataract”或“caterpillar”中的一个单词。如果没有括号,它将匹配“cataract”、“erpillar”或空字符串。
它将子模式设置为捕获子模式(如上所定义)。当整个模式匹配时,匹配子模式的主题字符串部分将通过 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
使用此模式,Sun
和 Sat
都将存储在反向引用 1 中。