Существует общий способ сбора шаблонных совпадений на протяжении всего произведения.
текста. Техника использует замену с
функция выражения команды :substitute
(см. :help sub-replace-\=
). Основная идея заключается в использовании замены
перечисление всех совпадений с образцом для оценки сохранения выражения
их без замены.
Во-первых, давайте рассмотрим сохранение матчей. Чтобы сохранить последовательность
из соответствующих фрагментов текста, удобно использовать список
(см. :help List
). Тем не менее, невозможно изменить список
напрямую, используя команду :let
, так как нет способа
запускать команды Ex в выражениях (включая \=
замещающие выражения).
Тем не менее, мы можем вызвать одну из функций, которые изменяют список на месте. За
Например, функция add()
предназначена для добавления данного элемента в
указанный список (см. :help add()
).
Другая проблема заключается в том, как избежать изменения текста во время работы
замена. Один из подходов состоит в том, чтобы шаблон всегда имел
совпадение нулевой ширины с добавлением \ze
или добавлением \zs
атомов к нему
(см. :help /\zs
, :help /\ze
). Шаблон, измененный таким образом
захватывает пустую строку, предшествующую или последующую вхождению
исходный шаблон в тексте (такие совпадения называются совпадения нулевой ширины
в Vim; см :help /zero-width
). Затем, если текст замены также
пусто, замена фактически ничего не меняет: она просто заменяет
совпадение нулевой ширины с пустой строкой.
Поскольку функция add()
, а также большая часть изменения списка
функции, возвращает ссылку на измененный список, для нашей техники
чтобы работать, нам нужно как-то получить пустую строку из него. Простейший
способ состоит в том, чтобы извлечь из него подсписок нулевой длины, указав диапазон
таких индексов, что начальный индекс больше конечного.
Объединяя вышеупомянутые идеи, мы получаем следующую команду Ex.
:let t=[] | %s/\<case\s\+\(\w\+\):\zs/\=add(t,submatch(1))[1:0]/g
После его выполнения все совпадения первой подгруппы накапливаются
в списке, на который ссылается переменная t
, и может использоваться как есть или
обрабатывается каким-то образом. Например, вставить содержимое списка один
по одной на отдельных строках в режиме вставки введите
Ctrl + R =t
Введите
Чтобы сделать то же самое в обычном режиме, просто используйте команду :put
:
:pu=t