根据this answer的评论,(?:(?!ab).)*
比(?!.*ab).*
更有效率。为什么?是不是先行/后视已经无法捕捉?
基本上,我试图弄明白我是否需要(\^(?:(?=(?:\d+=|\|$))))
或我是否可以(\^(?=\d+=|\|$))
。两者都可以通过^
或###=
..
|
示例:
1=5^2=A^3=6^|
我希望获得三场^
场比赛(我这样做)。所以,问题是:如果我还没有捕获前瞻的内容,我是否想要添加非捕获组?
答案 0 :(得分:2)
在您的情况下,您不需要捕获组,因为前瞻已经限制了更改的范围:
(\^(?:(?=(?:\d+=|\|$))))
可以在不改变功能的情况下重写
(\^(?=\d+=|\|$))
字符串开头的例子是别的,因为它在组内/组外使用重复。这里不仅有效率,还有可能的匹配:
(?:(?!ab).)*
匹配xxx
中的"xxxab"
,而
(?!.*ab).*
匹配b
。
答案 1 :(得分:2)
使用非捕获组对于处理您不一定要单独保留的重复模式非常有用。
例如,假设你正在解析人们的全名。一个人可以拥有任意数量的名字和中间名,但只有一个姓。您想要获取他们的全名以及他们的姓氏
您知道您可以使用重复的\w+\s+
来匹配名称段,但由于您不知道此人拥有多少首/中间名称,因此存在问题。
你考虑像^(\w+\s+)*(\w+)$
这样的东西。这个将捕获姓氏......但它是什么捕获组?如果不知道这个人有多少头号/中间名,就无从知晓。
这就是非捕获组进入的地方。您需要重复\w+\s+
模式,但您不一定关心它所抓取的具体值。
现在您的表达式看起来像^(?:\w+\s+)*(\w+)$
完整的结果是该人的全名,捕获组一是他们的姓。不再猜测结果的存储位置了!
在您的情况下,预测就足够了,但这并不意味着非捕获组没有它们的用途。