:h E65
可以看出,Vim的替代命令不允许有超过9个捕获组。例如,以下命令将起作用:
s/\v(a)(b)(c)(d)(e)(f)(g)(h)(i)/
但是这个带有一个捕获组的捕获将失败:
s/\v(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)/
我的问题不是关于它为什么失败(这是Vim的硬限制),而是关于为什么Vim根本没有这个限制吗?
此外,我知道具有9个捕获组的现实生活中的正则表达式可能非常难以阅读和维护,但我仍然感到好奇。
#1 楼
明显的原因是具有两个或多个数字的组是模棱两可的:将
视为组12,还是将其作为组1,后跟字符串2
?还有其他与效率相关的原因(指数匹配)时间之类的)。编写
ed
时,这些是塞子。从那时起,人们发现了更好的算法。评论
这是一个很好的可能性,您对此有任何参考/阅读吗?
– nobe4
16-09-22在16:11
@ nobe4对于歧义部分:不,但是IMO很明显。对于效率部分,您必须阅读有关正则表达式的早期实现。当时这是一个众所周知的问题。我没有确切的引文,但不难发现。
–佐藤桂
16-09-22在16:15
确实,这听起来完全合理。
–statox♦
16-09-22在16:16
是的,几乎可以肯定,解析器的编写目的是在反斜杠后寻找一位数字,并且从未更改过。很久以前,这已经足够普遍了。其他语言也提出了解决方法(例如,如果捕获中至少有11个,则仅考虑\ 11对捕获的引用,这虽然不一致,但通常还可以;对于反向引用和$则使用\ g {11}之类的东西) {11}代替),但vim从未引入过任何替代方法。
–霍布斯
16-09-22在17:07
评论
也许不仅与Vim有关:stackoverflow.com/a/10993346/2558252@ nobe4:有趣!因此,也许创建这些工具的人们认为超过9个小组是无用的...
我想这个限制来自vi,它继承了ed / sed的限制。几年前,我制作了一个补丁程序以支持多达99个群组,但并未包含在内。
@ChristianBrabandt一个更有用的补充是实现sed之类的数字标志:s /.../.../ 3将仅替换该模式的第3次出现。这可能是我在Vim中最想念的功能。
支持命名捕获将是缓解此问题的另一种方法。话虽这么说,但我经常看到9个捕获组附近的任何地方都是人们不知道他们可以使用非捕获组-\%()。