根据对这个答案的评论,(?:(?!ab).)*
比(?!.*ab).*
更有效率。为什么?向前看/向后看不是已经不捕捉了吗?
基本上,我想弄清楚我是否需要做(^(?:(?=(?:d+=||$))))
或如果我可以做(^(?=d+=||$))
。两者都可以捕获所有^
,然后是###=
或|
.
的例子:
1=5^2=A^3=6^|
我想得到三个^
匹配(我做)。那么,问题是:如果我已经没有捕获前瞻的内容,我还想添加非捕获组吗?
在您的示例中,您不需要捕获组,因为前瞻性已经限制了更改的范围:
(^(?:(?=(?:d+=||$))))
可以重写为
而不改变功能(^(?=d+=||$))
字符串开头的例子是另一回事,因为它在组内/组外使用了重复。这里有一个区别,不仅在效率上,而且在可能的匹配上:
(?:(?!ab).)*
匹配"xxxab"
中的xxx
,而
(?!.*ab).*
匹配b
使用非捕获组对于处理不需要单独保存的重复模式很有用。
例如,假设您正在解析人们的全名。一个人可以有任意数量的名和中间名,但只有一个姓。你想要捕捉他们的全名以及他们的姓。
你知道你可以用重复的w+s+
匹配名字片段,但是因为你不知道这个人有多少个名/中间名,这就出现了一个问题。
你可以考虑^(w+s+)*(w+)$
。这个将捕获姓氏…但是它属于哪个捕获组呢?如果不知道这个人有多少个名/中间名,是不可能知道的。
这就是非捕获组的用武之地。您需要重复w+s+
模式,但您不必关心它捕获的特定值。
现在你的表达式看起来像^(?:w+s+)*(w+)$
。
完整的结果是这个人的全名,捕获组一是他们的姓。不再猜测结果存储在哪里!
在您的例子中,预先查找应该足够了,但这并不意味着非捕获组没有它们的用途。