4.4 非捕获分组

还有一种分组是非捕获分组(Non-Capturing Group)。非捕获分组不会将其内容存储在内存中。在你并不想引用分组的时候,可以使用它。由于不存储内容,非捕获分组就会带来较高的性能,而运行本书的简单示例很难察觉到性能的提升。

还记得本章中讨论的第一个分组吗?就是这个:

  1. (the|The|THE)

你不需要任何后向引用,因此可以这样写一个非捕获分组:

  1. (?:the|The|THE)

回到本章开头,你可以添加选项将其变为不区分大小写的模式,就像这样:

  1. (?i)(?:the)

或者你也可以这样做:

  1. (?:(?i)the)

不过,下面这种写法最值得推荐:

  1. (?i:the)

该选项i可以放在问号和冒号之间。

原子分组

另一种非捕获分组是原子分组(atomic group)。如果你使用的正则表达式引擎进行回溯操作,这种分组就可以将回溯操作关闭,但它只针对原子分组内的部分,而不针对整个正则表达式。其语法如下:

  1. (?>the)

什么时候你会想使用原子分组呢?正则表达式处理过程缓慢的一个因素就是回溯操作。其原因就是回溯操作会尝试每一种可能性,这会消耗时间和计算资源。有时它会占用大量时间。回溯有可能产生巨大的负面效应,这被称为灾难性回溯

使用像re2(http://code.google.com/p/re2/)这样的非回溯引擎可彻底关闭回溯操作,而使用原子分组可以关闭正则表达式的部分回溯操作。

本书的重点是介绍语法,不讨论性能调优问题。在我看来,原子分组主要与性能相关。

接下来第5章我们学习字符组。