Я искал в Интернете ответ уже несколько недель, но все еще в растерянности ...

У меня есть файл (редактируется в VIM), содержащий многострочные записи - по сути, абзацы, разделенные "\n\n X", где X могут быть разными символами.

Мне нужно внутри vim найти все записи, которые содержат все искомые слова (и выделить искомые слова), возможно, когда эти слова сами являются шаблонами поиска.

Это можно выразить так: как мне сказать vim найти результаты шаблона многострочного поиска, где такие результаты не должны содержать последовательность "\n\n [aZ.,+* $ # @!] "(потому что такая последовательность разделяет искомые записи и всегда появляется внутри них).

Спасибо!

edit # 1: чтобы лучше объяснить, я добавляю 5 образцов записей, между каждой записью: \n \n \s_ \s \d+ (где \s - 0x20, а _ - один из нескольких возможных символов ascii):

 * 110000000018BBRT Phasellus aliquet blandit tellus,
sed sollicitudin augue accumsan vel.

 + 978000220019KML  Mauris et hendrerit dolor, a dapibus ante.
  * Vestibulum viverra ultricies urna.

 ! 020007005289KML  Vestibulum a malesuada enim.
Cras a efficitur est.
Suspendisse in nulla a justo finibus tincidunt.

 x 949317999999BTVN Sed facilisis massa eget mattis feugiat.
  o Interdum et malesuada fames ac ante ipsum primis in faucibus.

 v 949317999999BTV  Vestibulum at lectus at neque malesuada venenatis.
 Aliquam.

1 ответ1

0

Я не знаю, поможет ли это вам, но вот шаблон, который соответствует любой комбинации red и blue (в любом порядке), только если оба появляются в блоке, разделенном двумя пустыми строками (\n\n\n ; первая новая строка от конца последнего блока, затем два для новых строк; вам нужно адаптировать это к вашему точному разделителю).

Это основывается на базовом шаблоне, который соответствует как red и blue в линии в любом порядке:

/\%(red.*blue\)\|\%(blue.*red\)/

А затем расширяет простые .* Ветви (многострочные) блоки, между которыми нет \n\n\n .

Одна ветвь для red...blue блоков, а другая для blue...red блоков:

/\%(red\_.\{-}\%(\n\n\n\|blue\)\)\@>\%(blue\)\@<=/
/\%(blue\_.\{-}\%(\n\n\n\|red\)\)\@>\%(red\)\@<=/

Конечный результат просто объединяет оба и переключается на старый механизм регулярных выражений из-за ошибки в Vim.

/\%#=1\%(\%(red\_.\{-}\%(\n\n\n\|blue\)\)\@>\%(blue\)\@<=\)\|\%(blue\_.\{-}\%(\n\n\n\|red\)\)\@>\%(red\)\@<=/

Если это звучит непонятно или слишком сложно, возможно, нужен другой подход (например, сначала объединить все блоки в одну строку, что значительно облегчает сопоставление). Поскольку вы даете очень мало контекста и не имеете примерного содержания, я не могу комментировать дальше.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .