我正在阅读Groovy教程,他们讨论了如何通过使用?:
引导群组来创建不匹配的群组。这样一来,这个小组就不会出现在匹配者身上了。我不明白为什么你要明确说不匹配这个组。不把它放到一个小组中会不会更简单?
答案 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), )
会匹配并仍会返回one
或22
等所有群组。