用()分组
使用原子组
原子组的格式为 (?>...),并且在打开的 paren 之后具有 ?>。
请考虑以下示例文本:
ABC
正则表达式将尝试匹配从文本的位置 0 开始,即在 ABC 中的 A 之前。
如果使用不区分大小写的表达式 (?>a*)abc,(?>a*) 将匹配 1 A 字符,离开
BC
作为匹配的剩余文本。退出 (?>a*) 组,并尝试对剩余的文本进行 abc,该文本无法匹配。
引擎无法回溯到原子组,因此当前传递失败。引擎移动到文本中的下一个位置,该位置位于 A 之后和 B 之前的位置 1。
再次尝试 regex (?>a*)abc,(?>a*) 匹配 A 0 次,离开
BC
作为匹配的剩余文本。(?>a*) 组退出并尝试 abc,但失败了。
同样,引擎无法回溯到原子组,因此当前传递失败。正则表达式将继续失败,直到文本中的所有位置都已用完为止。
使用非原子组
常规非捕获组的格式为 (?:...),并且在打开的 paren 之后具有 ?:。
给定相同的示例文本,但使用不区分大小写的表达式 (?:a*)abc,将发生匹配,因为允许发生回溯。
首先,(?:a*) 将在文本中使用字母 A
ABC
离开
BC
作为匹配的剩余文本。退出 (?:a*) 组,并尝试对剩余的文本进行 abc,该文本无法匹配。
引擎回溯到 (?:a*) 组并尝试匹配少 1 个字符:它不是匹配 1 个 A 字符,而是尝试匹配 0 A 个字符,并退出 (?:a*) 组。这离开了
ABC
作为匹配的剩余文本。正则表达式现在能够成功匹配剩余的文本。
其他示例文本
考虑这个示例文本,包括原子和非原子组(同样,不区分大小写):
AAAABC
正则表达式将尝试匹配从文本的位置 0 开始,即在 AAAABC 中的第一个 A 之前。
使用原子组 (?>a*)abc 的模式将无法匹配,表现几乎与上面的原子 ABC 示例相同:所有 4 个 A 字符首先与 (?>a*) 匹配(留下 BC 作为剩余文本以匹配),并且 abc 无法匹配该文本。该组无法重新输入,因此匹配失败。
使用非原子组 (?:a*)abc 的模式将能够匹配,表现类似于上面的非原子 ABC 示例:所有 4 个 A 字符首先与 (?:a*) 匹配(留下 BC 作为匹配的剩余文本),并且 abc 无法匹配该文本。基团是能够重新输入,所以少了一个 A 尝试:3 个 A 字符匹配代替 4-(留下 ABC 作为剩余的文本相匹配),并且 abc 能够成功地匹配该文本。