用()分组

使用原子组

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