为什么\%(\)比Vim中的\(\)更快?

Léo*_* 준영 5 regex vim

我对文档感到困惑:

\%(\)由转义括号括起来的模式. */\%(\)* */\%(* *E53* 就像\(\),但不计算它作为子表达式.这允许使用更多组,并且它更快一点.

有人可以解释差异的原因吗?是因为回溯还是别的什么?

Jon*_*ler 11

"快一点"的评论是准确的,因为要完成的簿记要少一些,但重点在于"一点点"而不是"更快".基本上,通常情况下,\(pattern\)必须保留匹配的材料,以便您可以使用\3(适当的数量)在更换时参考它.在%该符号表示vim没有跟踪比赛的-所以它是做少一点的工作.


@SimpleQuestions问:

"跟踪比赛"是什么意思?它如何影响速度?

您可以使用转义括号来"捕获"匹配模式的某些部分.例如,假设我们正在使用简单的C函数声明 - 没有指向函数或其他括号源的指针 - 那么我们可能会有一个替换命令,如下所示:

s@\<\([a-zA-Z_][a-zA-Z_0-9]*\)(\([^)]*\))@xyz_\1(int nargs) /* \2 */@
Run Code Online (Sandbox Code Playgroud)

给定输入行,例如:

int simple_function(int a, char *b, double c)
Run Code Online (Sandbox Code Playgroud)

输出将是:

int xyz_simple_function(int nargs) /* int a, char *b, double c */
Run Code Online (Sandbox Code Playgroud)

(为什么你想这样做?我想我需要包装C函数,simple_function以便可以从编译为C的语言调用它使用不同的接口约定 - 它基于Informix 4GL,准确无误我正在用它来得到一个例子 - 不是因为你真的需要知道为什么这是一个很好的改变.)

现在,在本例中,\1\2在替换文本指的是正则表达式的所捕获的部分-的函数名(开头的字母字符字母数字的序列-计数下划线为"字母")和函数参数列表(一切在括号之间,但不包括括号).

如果我\%(....\)在函数标识符周围使用了符号,那么\1就会引用参数列表而没有\2.因为vim不必跟踪正则表达式的两个捕获部分中的一个,所以它比必须跟踪两个捕获的部分要少得多.但是,正如我所说,差异很小; 你可能永远不会在实践中测量它.这就是为什么手册说'它允许更多的团体'; 如果你需要对正则表达式的部分进行分组但不需要再次引用它们,那么你可以使用更长的正则表达式.然而,当正常表达中有超过9个被记住(捕获)的部分时,你的大脑通常会进行旋转而且你的手指无论如何都会犯错误 - 所以这种努力通常不值得.但是,我认为,这是使用\%(...\)符号的论据.它与(?:...)非捕获正则表达式的Perl(PCRE)符号相匹配.