首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非捕获组是多余的吗?

非捕获组是多余的吗?
EN

Stack Overflow用户
提问于 2015-07-19 10:57:17
回答 2查看 1.6K关注 0票数 9

可选的非捕获组是否多余?

是以下正则表达式:

代码语言:javascript
复制
(?:wo)?men

语义上等同于以下正则表达式?

代码语言:javascript
复制
(wo)?men
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-19 11:08:39

您的(?:wo)?men(wo)?men在语义上是等价的,但在技术上是不同的,即第一个是使用非捕获,另一个是使用捕获组。因此,问题在于,当我们有捕获组时,为什么使用非捕获组?

非圈养小组有时是有帮助的。

  1. 避免过多的反向引用(请记住,有时很难使用大于9的反向引用)
  2. 为了避免有99个编号的反向引用限制的问题(通过减少编号捕获组的数量)(来源:http://www.regular-expressions.info/backref.html:大多数regex版本最多支持99个捕获组和两位数的反向引用)。 注释--这与Java引擎无关,也不适用于.NET或.NET正则表达式引擎。
  3. 由于在堆栈中存储捕获而导致的减少开销
  4. 我们可以在现有正则表达式中添加更多的分组,而不会破坏捕获组的顺序。

而且,它只是使我们的火柴更干净

您可以使用非捕获组保留组织或分组的好处,但不需要捕获的开销。

重新分解现有的正则表达式以将捕获转换为非捕获组似乎不是一个好主意,因为它是可能会破坏密码或者需要花费太多的精力。

票数 12
EN

Stack Overflow用户

发布于 2022-06-02 03:23:31

其他地方的一个问题也是这样问的,我用Python给出了一个例子:

它并不“具有相同的效果”--在一种情况下,组被捕获和访问,而在另一种情况下,它只用于完成匹配。

当人们对访问组的值不感兴趣时,人们使用非捕获组来为多个匹配的情况节省空间,但在正则表达式引擎被优化的情况下,也是为了更好的性能。

在Python中有一个无用的例子来说明这一点:

代码语言:javascript
复制
from timeit import timeit
import re

chars = 'abcdefghij'
s = ''.join(chars[i % len(chars)] for i in range(100000))


def capturing():
    re.findall('(a(b(c(d(e(f(g(h(i(j))))))))))', s)


def noncapturing():
    re.findall('(?:a(?:b(?:c(?:d(?:e(?:f(?:g(?:h(?:i(j))))))))))', s)


print(timeit(capturing, number=1000))
print(timeit(noncapturing, number=1000))

输出:

代码语言:javascript
复制
5.8383678999998665
1.0528525999998237

注意:这是尽管PyCharm (如果您碰巧使用它)警告“不必要的非捕获组”-警告是正确的,但不是全部事实,很明显。这在逻辑上是不必要的,但肯定没有同样的实际效果。

如果您想要消除这些警告的原因是为了抑制这些警告,那么PyCharm允许您这样做:

代码语言:javascript
复制
# noinspection RegExpUnnecessaryNonCapturingGroup
re.findall('(?:a(?:b(?:c(?:d(?:e(?:f(?:g(?:h(?:i(j))))))))))', s)

书呆子的另一个注意事项:上面的例子在逻辑上也不是完全等价的。但它们匹配相同的字符串,只是结果不同。

代码语言:javascript
复制
c = re.findall('(a(b(c(d(e(f(g(h(i(j))))))))))', s)
nc = re.findall('(?:a(?:b(?:c(?:d(?:e(?:f(?:g(?:h(?:i(j))))))))))', s)

c是10元组([('abcdefghij', 'bcdefghij', ..), ..])的列表,而nc是单个字符串(['j', ..])的列表。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31500422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档