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.*/"
1 ответ
Общая теория
Vimscript оценивается точно так же, как команды Ex, набранные в :
командная строка. Там не было переменных в ex
поэтому нет возможности их указать. При вводе команды в интерактивном режиме, вы, вероятно, будете использовать <C-R>=
вставить переменное содержимое:
:sleep <C-R>=timetowait<CR>m<CR>
... но в сценарии, :execute
должен быть использован. Все литеральные части команды Ex должны быть заключены в кавычки (одинарные или двойные кавычки), а затем объединены с переменными:
execute 'sleep' timetowait . 'm'
Твоя проблема
Для сценария синтаксиса вы бы использовали execute
, Кроме того, обратите внимание, что конкатенация строк в Vim выполняется с .
, не с +
, (Также обратите внимание, что я использую одинарные кавычки, чтобы избежать обратной косой черты.)
execute 'syn match Title /\%>0l\%<' . b:title_until . 'l.*/'
Кроме того, вы можете использовать printf()
; это менее загромождено, когда есть многократные переменные. Тем не менее, здесь вы должны учитывать, что %
должно быть удвоено:
execute printf('syn match Title /\%%>0l\%%<%sl.*/', b:title_until)
Заключительные советы
\%>0l
является излишним и может быть опущен, так как он всегда будет совпадать: отрицательных строк нет.