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

时间:2009-04-11 22:14:31

标签: regex vim

我对文档感到困惑:

  

\%(\)由转义包围的模式   括弧。 */\%(\)* */\%(* *E53*   就像\(\)一样,但不计算在内   它作为一个子表达式。这允许   使用更多的组,这是一点点   更快。

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

2 个答案:

答案 0 :(得分:11)

“快一点”的评论是准确的,因为要完成的簿记要少一些,但重点是“一点点”而不是“更快”。基本上,通常情况下,必须保留与\(pattern\)匹配的材料,以便您可以使用\3(适当的数字)在替换中引用它。 %表示vim表示s@\<\([a-zA-Z_][a-zA-Z_0-9]*\)(\([^)]*\))@xyz_\1(int nargs) /* \2 */@ 无需跟踪匹配 - 因此它的工作量减少了。


@SimpleQuestions问:

  

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

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

int simple_function(int a, char *b, double c)

给定输入行,例如:

int xyz_simple_function(int nargs) /* int a, char *b, double c */

输出将是:

simple_function

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

现在,在示例中,替换文本中的\2\%(....\)指的是正则表达式的捕获部分 - 函数名称(以字母字符开头的字母数字序列 - 计数下划线为'alphabetic')和函数参数列表(括号之间的所有内容,但不包括括号)。

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

答案 1 :(得分:4)

我在#Vim问道,由于回溯,对方是否更快。用户godlygeek回答:

  

不,它更快,因为匹配的东西不需要进行限制 - 任何不必要的工作对语法文件都是坏事。

他继续说道:

  

[速度]取决于有多大   字符串是。对于3个字符,它   对于3000而言并不重要   可能会。请记住这一点   它每次都需要被限制   匹配....包括在期间   回溯......这意味着甚至   3个字符可能是strdup'ed   在匹配过程中1000次   一个正则表达式。 - 语法文件   在$ VIMRUNTIME /语法