如何在正则表达式中使用非捕获组,即(?:),它们有什么好处?


当前回答

我不能评论最上面的答案来这样说:我想补充一个明确的观点,这只是在最上面的回答中暗示的:

非捕获组(?…)不会从原始完全匹配中删除任何字符,它只会对程序员进行可视化的正则表达式重组。

要访问正则表达式的特定部分而不定义外来字符,您将始终需要使用.group(<index>)

其他回答

?: 当您想对表达式进行分组,但不想将其保存为字符串的匹配/捕获部分时,使用。

一个例子是匹配IP地址:

/(?:\d{1,3}\.){3}\d{1,3}/

请注意,我不在乎保存前3个八位字节,但(?:…)分组允许我缩短正则表达式,而不会导致捕获和存储匹配项的开销。

让我举一个地理坐标的例子,下面是两组

Latitude,Longitude

([+-]?\d+(?:\.\d+)?),([+-]?\d+(?:\.\d+)?)

让我们拿一个([+-]?\d+(?:\.\d+)?)

坐标可以是58这样的整数,也可以是58.666因此,可选的(.666)第二部分(\.\d+)?被提及。

(...)? - for optional

但这是加括号的,这将是另一组匹配。我们不需要两场比赛,一场58分,另一场666分,我们需要一个纬度作为比赛。这里是非捕获组(?:)

与非捕获组[+-]?\d+(?:\.\d+)?,58.666和58都是单场比赛

捕获的组可以稍后在正则表达式中使用以匹配,也可以在正则表达式的替换部分中使用它们。创建一个非捕获组只会使该组免于出于以下原因之一而被使用。

如果你试图捕捉很多不同的东西,而有些群体你不想捕捉,那么非捕捉群体是很好的。

这就是它们存在的原因。当你学习团体时,学习原子团体,他们做了很多!也有环视组,但它们有点复杂,而且使用得不多。

稍后在正则表达式中使用的示例(backreference):

<([A-Z][A-Z0-9]*)\b[^>]*>.*</\1> [查找xml标记(不支持ns)]

([A-Z][A-Z0-9]*)是一个捕获组(在本例中是标记名)

稍后在正则表达式中是\ 1,这意味着它将仅与第一组([A-Z][A-Z0-9]*)中的相同文本匹配(在本例中,它与结束标记匹配)。

简单的答案

使用它们来确保在这里出现几种可能性中的一种(?:一个|两个)或可选短语camp(?:站点)?或者一般来说,任何你想建立一个组/短语/部分而不需要特别提及的地方。

他们将您捕获的组数保持在最小值。

我是一名JavaScript开发人员,将尝试解释其与JavaScript相关的意义。

考虑一个场景,你想将猫与动物相匹配当你想要匹配猫和动物时,两者之间应该有一个平衡点。

 // this will ignore "is" as that's is what we want
"cat is animal".match(/(cat)(?: is )(animal)/) ;
result ["cat is animal", "cat", "animal"]

 // using lookahead pattern it will match only "cat" we can
 // use lookahead but the problem is we can not give anything
 // at the back of lookahead pattern
"cat is animal".match(/cat(?= is animal)/) ;
result ["cat"]

 //so I gave another grouping parenthesis for animal
 // in lookahead pattern to match animal as well
"cat is animal".match(/(cat)(?= is (animal))/) ;
result ["cat", "cat", "animal"]

 // we got extra cat in above example so removing another grouping
"cat is animal".match(/cat(?= is (animal))/) ;
result ["cat", "animal"]