用()分组
使用原子组
原子组的格式为 (?>...)
,并且在打开的 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
能够成功地匹配该文本。