Vim:如何动态创建正则表达式模式

ska*_*sie 2 vi vim

我想将变量连接到正则表达式模式中。例如,考虑使用此模式来匹配第 1 行到第 3 行的语法。

syn match Title /\%>0l\%<4l.*/

我希望能够动态设置模式中的第二个整数(上例中的“4”为任何值b:title_until)。我尝试过字符串连接,但它不起作用。下面的例子的意图应该很清楚:

let b:title_until = 10

if exists("b:title_until")
  syn match Title "/\%>0l\%<" + b:title_until + "l.*/"
end
----------------------------------------------------------------------
> (NFA) Unknown operator '\%
> Invalid character after \%
> Invalid argument: Title "/\%>0l\%<" + b:title_until + "l.*/"
Run Code Online (Sandbox Code Playgroud)

Ing*_*kat 5

一般理论

Vimscript 的评估与在命令行中键入的 Ex 命令完全相同:。中没有变量ex,因此无法指定它们。以交互方式键入命令时,您可能会用来<C-R>=插入变量内容:

:sleep <C-R>=timetowait<CR>m<CR>
Run Code Online (Sandbox Code Playgroud)

...但在脚本中,:execute必须使用。Ex 命令的所有文字部分都必须用引号引起来(单引号或双引号),然后与变量连接:

execute 'sleep' timetowait . 'm'
Run Code Online (Sandbox Code Playgroud)

你的问题

对于语法脚本,您可以使用execute. 另外,请注意,Vim 中的字符串连接是通过 完成的.,而不是通过 完成的+。(另请注意,我使用单引号以避免反斜杠转义。)

execute 'syn match Title /\%>0l\%<' . b:title_until . 'l.*/'
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用printf(); 当有多个变量时,这不会那么混乱。但是,这里您需要考虑%必须加倍:

execute printf('syn match Title /\%%>0l\%%<%sl.*/', b:title_until)
Run Code Online (Sandbox Code Playgroud)

最后的提示

\%>0l多余的,可以省略,因为它总是匹配:没有负行。