我们什么时候需要使用非捕获组?

时间:2014-07-02 17:03:45

标签: regex

根据this answer的评论,(?:(?!ab).)*(?!.*ab).*更有效率。为什么?是不是先行/后视已经无法捕捉?

基本上,我试图弄明白我是否需要(\^(?:(?=(?:\d+=|\|$))))或我是否可以(\^(?=\d+=|\|$))。两者都可以通过^###= ..

来捕获所有|

示例:

1=5^2=A^3=6^|

我希望获得三场^场比赛(我这样做)。所以,问题是:如果我还没有捕获前瞻的内容,我是否想要添加非捕获组?

2 个答案:

答案 0 :(得分:2)

在您的情况下,您不需要捕获组,因为前瞻已经限制了更改的范围:

(\^(?:(?=(?:\d+=|\|$))))

可以在不改变功能的情况下重写

(\^(?=\d+=|\|$))

字符串开头的例子是别的,因为它在组内/组外使用重复。这里不仅有效率,还有可能的匹配:

(?:(?!ab).)*

匹配xxx中的"xxxab",而

(?!.*ab).*

匹配b

答案 1 :(得分:2)

使用非捕获组对于处理您不一定要单独保留的重复模式非常有用。

例如,假设你正在解析人们的全名。一个人可以拥有任意数量的名字和中间名,但只有一个姓。您想要获取他们的全名以及他们的姓氏 您知道您可以使用重复的\w+\s+来匹配名称段,但由于您不知道此人拥有多少首/中间名称,因此存在问题。
你考虑像^(\w+\s+)*(\w+)$这样的东西。这个捕获姓氏......但它是什么捕获组?如果不知道这个人有多少头号/中间名,就无从知晓。

这就是非捕获组进入的地方。您需要重复\w+\s+模式,但您不一定关心它所抓取的具体值。
现在您的表达式看起来像^(?:\w+\s+)*(\w+)$ 完整的结果是该人的全名,捕获组一是他们的姓。不再猜测结果的存储位置了!


在您的情况下,预测就足够了,但这并不意味着非捕获组没有它们的用途。