Vim Regex ИЛИ в шаблоне имени файла в Windows - PullRequest
1 голос
/ 27 января 2012

Я пытаюсь сформулировать регулярное выражение, которое совпадает с именами набора файлов, которые я хотел бы пакетно обработать в Vim, но обнаружил, что не могу использовать \ | (регулярное выражение ИЛИ), как и ожидалось ...

В частности, я хотел бы создать список аргументов, состоящий из следующих файлов в текущем каталоге:

f0148.e, f0149.e, f0150.e ... f0159.e (i.e., 12 files total)

Введенная мной команда vim выглядит следующим образом:

:arg f01\(\(4[89]\)\|\(5[0-9]\)\).e

Vim выполняет эту команду без какого-либо заметного результата - сообщения отсутствуют, а вывод из: args остается неизменным (не выдает требуемый список имен файлов).

Если я разделю регулярное выражение на: :arg f01\(\(4[89]\)\).e (примечание: оставляя скобки здесь, как в приведенном выше полном выражении)
... и ...

:arg f01\(\(5[0-9]\)\).e

... затем :args производит f0148.e f0149.e и f0150.e ... f0159.e соответственно (по желанию).

Кроме того, если я введу вышеупомянутый список имен файлов в текстовом файле и использую вышеупомянутое регулярное выражение в качестве шаблона поиска (т. Е. /f01\(\(4[89]\)\|\(5[0-9]\)\).e), он будет работать так же, как требуется.

Таким образом, я определил, что чередование (\|) каким-то образом приводит к сбою выражения. Обратите внимание, что я использую Vim в Windows 7, если это важно (так как обратная косая черта и труба являются допустимыми символами в командной строке Windows).

Быстрый обходной путь будет использовать:

:arg f014[89].e
:argadd f015[0-9].e

... но мне бы очень хотелось выяснить, как заставить работать вышеупомянутое регулярное выражение.

Спасибо за вашу помощь!

1 Ответ

2 голосов
/ 27 января 2012

Я мог бы предложить:

:let file_list = filter(split(globpath('.','**'),nr2char(10)), 'v:val =~ ''f01\(\(4[89]\)\|\(5[0-9]\)\)\.e'' ')
:execute 'args ' . join(map(file_list,'fnameescape(v:val)'),' ') 

Как это работает:

  • globpath('.','**') создает список всех файлов в текущем каталоге и всех подкаталогах.:help globpath().
  • split(..., nr2char(10)) создаст его список, поскольку разделителем был перевод строки
  • filter(..., 'v:val =~ ''pattern'' '), который фильтрует список, сохраняя только элементы, соответствующие шаблону.:help v:val.Удвоение одинарной кавычки позволяет избежать их в строке одинарной кавычки.
  • map(..., fnameescape()) экранирует все пробелы и обратные косые черты
  • join() добавляет пробелы между именами файлов

Если выЕсли вы хотите сделать это функцией, вы можете поместить это в свой vimrc:

function! ArgsPattern(pat)
  let file_list = filter(split(globpath('.','**'),nr2char(10)), 'v:val =~ ''' . substitute(a:pat,"'","''",'g') . '''')
  execute 'args ' . join(map(file_list,'fnameescape(v:val)'),' ') 
endfunction
command! -nargs=+ ArgsPattern call ArgsPattern(<q-args>)

И тогда вам нужно только сделать:

:ArgsPattern f01\(\(4[89]\)\|\(5[0-9]\)\)\.e

Обратите внимание, что если нет совпадения, тоКоманда execute внутри функции оценивается как :args, и поэтому список ваших текущих аргументов выводится на печать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...