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 является излишним и может быть опущен, так как он всегда будет совпадать: отрицательных строк нет.

Другие вопросы по тегам