我对文档感到困惑:
\%(\)
由转义包围的模式 括弧。*/\%(\)* */\%(*
*E53*
就像\(\)
一样,但不计算在内 它作为一个子表达式。这允许 使用更多的组,这是一点点 更快。
有人可以解释差异的原因吗?是因为回溯还是别的什么?
答案 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 /语法
中