Regex для вставки пробела в vim - PullRequest
14 голосов
/ 06 декабря 2011

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

Если я начну с:

foo:bar

Я бы хотел закончить с

foo: bar

Я дошел до %s/:[a-z], но теперь я не знаючто делать для следующей части %s оператора.

Кроме того, как мне изменить оператор :[a-z], чтобы убедиться, что он перехватывает все, что не является пробелом?

Ответы [ 4 ]

22 голосов
/ 07 декабря 2011

:%s/:\(\S\)/: \1/g

\S соответствует любому символу, который не является пробелом, но вы должны помнить, что это за символ без пробелов.Это то, что делает \(\).Затем вы можете обратиться к нему, используя \1 в замене.

Таким образом, вы сопоставите :, некоторый непробельный символ, а затем замените его на :, пробел и захваченный символ.


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

:%s/:\@!<:[^:[:space:]]\@=/: /g

  • :\@!< соответствует любому не :, включаяначало линии.Это важная характеристика негативных утверждений.Это не требует, чтобы на самом деле был персонаж, просто не существует :.

  • :, соответствующего требуемому двоеточию.

  • [^:[:space:]] вводит еще пару концепций регулярных выражений.

    • Внешний [] - это коллекция.Коллекция используется для соответствия любому из символов, перечисленных внутри.Однако ведущий ^ отрицает это совпадение.Так, [abc123] будет соответствовать a, b, c, 1, 2 или 3, но [^abc123] соответствует любому, кроме этих символов.

    • [:space:] - это класс символов.Классы символов могут использоваться только внутри коллекции.[:space:] означает, что неудивительно, что любые пробелы.В большинстве реализаций это относится непосредственно к результату функции isspace библиотеки C.

    Связывая все вместе, коллекция означает "соответствовать любому символу, который не является :или пробел ".

  • \@= является положительным прогнозным утверждением.Он применяется к предыдущему элементу (в данном случае к коллекции) и означает, что коллекция необходима для успешного сопоставления шаблона, но не будет частью заменяемого текста.

Таким образом, когда образец совпадает, мы просто заменяем : на себя и пробел.

7 голосов
/ 07 декабря 2011

Интересной особенностью регулярного выражения Vim является наличие \zs и \ze. Они могут быть и у других двигателей, но они не очень распространены.

Цель \zs - отметить начало матча, а \ze его конец. Например:

ab\zsc

соответствует c, только если до этого у вас есть ab. Точно так же:

a\zebc

соответствует a, только если после него есть bc. Вы можете смешать оба:

a\zsb\zec

соответствует b только если находится между a и c. Вы также можете создавать совпадения нулевой ширины, которые идеально подходят для того, что вы пытаетесь сделать:

:%s/:\zs\ze\S/ /

Ваш поиск не имеет размера, только позиция. И их вы заменяете эту позицию на "". Кстати, \S означает любой символ, кроме пробелов.

:\zs\ze\S соответствует позиции между двоеточием и чем-то, кроме пробела.

7 голосов
/ 07 декабря 2011

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

:%s/: \@!/: /g

\@! - это негативный взгляд.

4 голосов
/ 07 декабря 2011

Вы, вероятно, хотите использовать :[^ ] для обработки всего, кроме пробелов. Как упомянул Мэтт, это приведет к тому, что ваша замена заменит дополнительный символ.
Есть несколько способов избежать этого, вот два, которые я считаю полезными.
1) Окружите последнюю часть поискового термина круглыми скобками \(\), это позволяет вам ссылаться на эту часть поиска в вашем заменяющем термине с /1.
Ваша последняя строка замены должна выглядеть так:

%s/:\([^ ]\)/: \1/g

2) досрочно завершить поисковый запрос \ze Это будет означать, что для поиска совпадения должен быть выполнен весь поисковый термин, но только часть перед \ze будет выделена или заменена
Ваша последняя строка замены должна выглядеть так:

%s/:\ze[^ ]/: /g
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...