子模式

子模式由括号(圆括号)分隔,可以嵌套。将模式的一部分标记为子模式会做两件事

  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 中。

添加笔记

用户贡献的笔记 1 条笔记

mike at eastghost dot com
9 年前
(?:(?!string).)

?: 创建一个子模式

?! 是一个负向前瞻。

在点号之前放置负向前瞻会导致正则表达式引擎首先查找负向前瞻字符串的任何出现,只有在不存在负向前瞻字符串的情况下,才应该匹配任意字符(由于点号)。
To Top