#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 или более строкам, помечается только первая строка соответствия, и данная команда будет выполнена по этому адресу.