глобальная команда vim, сопоставляющая несколько строк и объединяющая их

#re&ex #vim

#регулярное выражение #vim

Вопрос:

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

 acc abcd etc. etc.
// line 1
// line 2
acc more words
// 3-4 more lines
acc some other words
  

Некоторые строки начинаются с acc , а некоторые — нет. Я хочу объединить строки, не начинающиеся с acc , с теми, которые начинаются с нее, и по-прежнему разделяться на @@ , чтобы в моем файле после операции были только строки, начинающиеся с acc :

 acc abcd etc. etc.@@//line 1@@//line 2
acc more words@@//3-4 more lines
acc some other words
  

Я попробовал приведенную ниже команду, используя &lobal для разделения каждого набора строк и замены n на @@ :

 :%&/^acc.*_.{-}(^acc)@=/s/n/@@/&
  

Но я могу получить только первую n замену на @@ внутри каждого сопоставления с шаблоном :& .

Что я делаю не так в этой команде? Есть ли более простой способ сделать это? Спасибо.

Комментарии:

1. (^acc) не похоже, что она будет соответствовать началу строки, за которой следует acc . Я думаю, вам нужно использовать (_^acc) вместо этого, см. :help ordinary-atom .

2. но, похоже, это ничего не изменило… Неважно.

Ответ №1:

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

Например:

 :v/^acc/s/^/@@
:%s/n^@@/@@/
  

Объяснение:

  • добавляйте каждую строку, не начинающуюся с acc , к @@ ,
  • заменяйте каждую новую строку, за которой следует @@ with @@ , эффективно соединяя все @@ строки вместе и с acc строками.

Комментарии:

1. Спасибо, ваше решение работает. Но из любопытства, есть ли способ заставить : & работать с несколькими строками, потому что сопоставленный шаблон находится во многих строках. Я понимаю, что мое решение не сработало, потому что search-replace выполнялся только в строках, с которых начинался шаблон, а не в последующих строках, которые также были частью шаблона, сопоставляемого с помощью :&.

2. :&lobal работает следующим образом: 1. она помечает совпадающие строки в заданном диапазоне, 2. она выполняет указанную команду для каждой отмеченной строки. Независимо от того, соответствует ли ваш шаблон 1 или более строкам, помечается только первая строка соответствия, и данная команда будет выполнена по этому адресу.