可选的非捕获组是否多余?
是以下正则表达式:
(?:wo)?men语义上等同于以下正则表达式?
(wo)?men发布于 2015-07-19 11:08:39
您的(?:wo)?men和(wo)?men在语义上是等价的,但在技术上是不同的,即第一个是使用非捕获,另一个是使用捕获组。因此,问题在于,当我们有捕获组时,为什么使用非捕获组?
非圈养小组有时是有帮助的。
而且,它只是使我们的火柴更干净
您可以使用非捕获组保留组织或分组的好处,但不需要捕获的开销。
重新分解现有的正则表达式以将捕获转换为非捕获组似乎不是一个好主意,因为它是可能会破坏密码或者需要花费太多的精力。
发布于 2022-06-02 03:23:31
其他地方的一个问题也是这样问的,我用Python给出了一个例子:
它并不“具有相同的效果”--在一种情况下,组被捕获和访问,而在另一种情况下,它只用于完成匹配。
当人们对访问组的值不感兴趣时,人们使用非捕获组来为多个匹配的情况节省空间,但在正则表达式引擎被优化的情况下,也是为了更好的性能。
在Python中有一个无用的例子来说明这一点:
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))输出:
5.8383678999998665
1.0528525999998237注意:这是尽管PyCharm (如果您碰巧使用它)警告“不必要的非捕获组”-警告是正确的,但不是全部事实,很明显。这在逻辑上是不必要的,但肯定没有同样的实际效果。
如果您想要消除这些警告的原因是为了抑制这些警告,那么PyCharm允许您这样做:
# noinspection RegExpUnnecessaryNonCapturingGroup
re.findall('(?:a(?:b(?:c(?:d(?:e(?:f(?:g(?:h(?:i(j))))))))))', s)书呆子的另一个注意事项:上面的例子在逻辑上也不是完全等价的。但它们匹配相同的字符串,只是结果不同。
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', ..])的列表。
https://stackoverflow.com/questions/31500422
复制相似问题