不匹配组的目的是什么?

时间:2013-11-01 02:30:41

标签: regex groovy matcher capture-group

我正在阅读Groovy教程,他们讨论了如何通过使用?:引导群组来创建不匹配的群组。这样一来,这个小组就不会出现在匹配者身上了。我不明白为什么你要明确说不匹配这个组。不把它放到一个小组中会不会更简单?

2 个答案:

答案 0 :(得分:3)

?:用于分组,但是当您不想捕获它们时。这对于简洁的代码很有用,有时也是非常必要的。这有助于在匹配之后不存储我们随后不需要的东西,从而节省空间。

它们也主要与|运算符一起使用。

  

交替运算符具有所有正则表达式的最低优先级   运营商。也就是说,它告诉正则表达式引擎匹配   垂直条左侧的所有内容,或右侧的所有内容   垂直条。如果你想限制的范围   交替,您需要使用括号进行分组。   (http://www.regular-expressions.info/alternation.html)。

在这种情况下,您不能在不将它们放入组中的情况下离开它们。你需要在许多通常的正则表达式中使用交替运算符,例如电子邮件,网址等。希望有所帮助。

/(?:http|ftp):\/\/([^\/\r\n]+)(\/[^\r\n]*)?/g是JavaScript中的示例URL正则表达式,需要交替运算符并需要分组。如果没有分组,匹配对于所有http网址只有http

答案 1 :(得分:1)

使用非捕获组至少有四个原因:

1)保存内存:当您匹配捕获组时,无论您是否需要,该组的内容都会独立存储在内存中。当您使用正则表达式并将结果存储在大量数据集上时,内存中的空间可以快速累加。例如,[0-9]+(, [0-9]+)*将匹配由逗号和空格分隔的一系列整数,如15, 13, 14。假设您只需要结果中的完整匹配字符串(组0)。但是,在这种情况下,您实际上将存储"15, 13, 14"", 14",因为后者位于捕获的组中。您可以使用[0-9]+(?:, [0-9]+)*来节省内存和时间。对于这样一个简单而简短的例子来说,这可能并不重要,但是对于更复杂的正则表达式,那些额外的内存使用量会加快。作为奖励,非捕获组的处理速度也更快。

2)更简单的代码:如果你有一个像([a-z]+)( \.)* ([a-z]+) ([a-z]+)这样的正则表达式,想要提取三个单词,你需要使用第1,3和4组。虽然这并不十分困难,但想象一下,您需要在后两个单词之间添加另一个组,例如([a-z]+)( \.)* ([a-z]+)( \.)* ([a-z]+)。如果您稍后在代码中的多个位置使用这些组,则可能很难跟踪它们。相反,您可以先写([a-z]+)(?: \.)* ([a-z]+) ([a-z]+),然后再将其更改为([a-z]+)(?: \.*) ([a-z]+)(?: \.)* ([a-z]+),两者分别与第1组,第2组和第3组匹配。

3)外部依赖:您可能有一个函数或库需要接收正好n组的正则表达式匹配。这是一个不寻常的实例,但是使所有其他组无法捕获将满足要求。

4)组计数限制:大多数语言都限制正则表达式中的捕获组总数。需要那么多组(例如100个用于python)是不可能的,这是可能的。您可以使用较少的组,并通过使用不受此类限制的非捕获组来减少此限制。例如:

((one|1), )((two|2), )…((nine_hundred_ninety_nine|999), )

其中是所有中间组在某些语言中不匹配,因为它有太多的捕获组。但是:

(?:(one|1), )(?:(two|2), )…(?:(nine_hundred_ninety_nine|999), )

会匹配并仍会返回one22等所有群组。