正则表达式非捕获组 - 无用?

时间:2014-08-11 19:45:50

标签: javascript regex

我试图理解这个概念,但我真的看不出它是如何有用的,所以我假设我错过了这一点。

例如 -

此正则表达式/([0-9]+)(?:st|nd|rd|th)?/将匹配带或不带“st”,“rd”等后缀的数字。

所以"1st".match(/([0-9]+)(?:st|nd|rd|th)?/g)返回[“1st”]

"1".match(/([0-9]+)(?:st|nd|rd|th)?/g)返回[“1”]

然而,这仍然完全相同没有(?:) par!

"1st".match(/([0-9]+)(st|nd|rd|th)?/g)返回[“1st”]

...谢谢

4 个答案:

答案 0 :(得分:4)

非捕获分组更快,因为正则表达式引擎不必跟踪匹配。为了清晰起见,最好不要捕获不需要捕获的内容。例如:

(foo|bar)((z|q)s?)?

这有点人为,但您可以轻松地将其应用于真正的正则表达式。您可以匹配foozfoozs。我们对foobar部分以及zq感兴趣,但我们并不关心可选的s。那么哪个部分是zq?是捕获组2还是3?想象一下,如果我们改为(?:(z|q)。现在,我们知道只有两个捕获组,所以我们不必进行这种精神跳跃。


有时需要非捕获,例如JavaScript的.split

  

如果分隔符包含捕获括号,则在数组中返回匹配的结果。

如果要对分组使用分组,但又不想在数组中包含分割正则表达式,则必须使用非捕获组。

答案 1 :(得分:2)

您没有看到差异,因为您的正则表达式具有global flag,使用match时只会产生一个包含整个字符串的所有结果的数组。试试这个(不用g)代替:

> "1st".match(/([0-9]+)(?:st|nd|rd|th)?/)
["1st", "1"]
> "1".match(/([0-9]+)(?:st|nd|rd|th)?/)
["1", "1"]
> "1st".match(/([0-9]+)(st|nd|rd|th)?/)
["1st", "1", "st"]

使用exec method会有相同的行为。

答案 2 :(得分:1)

当您拥有包含许多捕获组的非常复杂的正则表达式时,它非常有用,并且您不希望使用仅用于构造正则表达式的组来混淆您的代码。你要避免"组1是数据A,组2是数据B,组3和4是垃圾,组5是数据C"场景。

非捕获组也稍快一些。

答案 3 :(得分:0)

来自python' re'文档: https://docs.python.org/2/library/re.html

常规括号的非捕获版本。匹配括号内的正则表达式,但在执行匹配后或在模式中稍后引用时,无法检索组匹配的子字符串。