为什么Vim正则表达式不允许超过9个捕获组?


16

从中:h E65我们可以看到,Vim在替换命令中不允许超过9个捕获组。

例如,以下命令将起作用:

s/\v(a)(b)(c)(d)(e)(f)(g)(h)(i)/\9\8\7\6\5\4\3\2\1

但是,这个带有一个捕获组的捕获组将失败:

s/\v(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)/\10\9\8\7\6\5\4\3\2\1

我的问题不是关于为什么失败(这是Vim的硬限制),而是关于为什么Vim根本没有这个限制?

另外,我知道具有超过9个捕获组的真实正则表达式可能很难阅读和维护,但我仍然很好奇。


2
也许不仅与Vim有关:stackoverflow.com/a/10993346/2558252
nobe4 2016年

1
@ nobe4:有趣!因此,也许创建这些工具的人们认为超过9个小组是无用的……
statox

我想这个限制来自vi,它继承了ed / sed的限制。几年前,我制作了补丁程序以支持多达99个团体,但其中并未包括在内
Christian Brabandt

1
@ChristianBrabandt一个更有用的补充是实现数字标记,例如seds/.../.../3将仅替换模式的第3次出现。这可能是我在Vim中最想念的功能。
佐藤桂

2
支持命名捕获将是缓解此问题的另一种方法。话虽这么说,但我通常看到9个捕获组附近的任何地方都是人们不知道他们可以使用非捕获组- \%()
jamessan

Answers:


24

明显的原因是具有两个或多个数字的组是不明确的:应\12被视为组12或组1,后跟字符串2

还有其他与效率有关的原因(指数匹配时间等)。这些ed是写的时候的表演塞子。从那时起,人们发现了更好的算法。


这是一个很好的可能性,您对此有任何参考/阅读吗?
nobe4

2
@ nobe4对于歧义部分:不,但是IMO很明显。对于效率部分,您必须阅读有关正则表达式的早期实现。当时这是一个众所周知的问题。我没有确切的引文,但不难发现。
佐藤桂2016年

确实,这听起来完全合理。
statox

4
是的,几乎可以肯定,解析器的编写目的是在反斜杠后寻找一位数字,并且从未更改过。很久以前,这已经足够普遍了。其他语言也提出了解决方法(例如,仅\11当捕获中至少有11种时才考虑对捕获的引用,这虽然不一致,但通常还可以;以及诸如\g{11}反向引用和${11}替代之类的东西),但是vim从来没有介绍了其中任何一个。
hobbs
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.