Регулярное выражение для вставки пространства в vim
Я являюсь регулярным регулярным выражением (просто читая свои первые статьи о них) и в то же время работаю над более сильным использованием vim. Я хотел бы использовать регулярное выражение для поиска всех экземпляров двоеточия :
, за которыми не следует пробел и вставить одно пространство между этими двоеточиями и любым символом после их.
Если я начинаю с:
foo:bar
Я хотел бы закончить с
foo: bar
Я дошел до %s/:[a-z]
, но теперь я не знаю, что делать для следующей части инструкции %s
.
Также, как мне изменить оператор :[a-z]
, чтобы убедиться, что он ловит все, что не является пространством?
Ответы
Ответ 1
:%s/:\(\S\)/: \1/g
\S
соответствует любому символу, который не является пробелом, но вам нужно помнить, что это за символ без пробелов. Это то, что делает \(\)
. Затем вы можете обратиться к нему с помощью \1
в замене.
Итак, вы сопоставляете :
, некоторый символ без пробелов, а затем заменяете его :
, пробелом и захваченным символом.
Изменение этого параметра только для изменения текста, если только один :
достаточно прост. Как предполагали другие, полезно использовать некоторые из утверждений нулевой ширины.
:%s/:\@!<:[^:[:space:]]\@=/: /g
-
:\@!<
соответствует любому не :
, включая начало строки. Это важная характеристика отрицательных утверждений о взгляде/взгляде. Это не требует, чтобы на самом деле был символ, просто нет :
.
-
:
соответствует требуемому двоеточию.
-
[^:[:space:]]
вводит еще несколько концепций регулярных выражений.
-
Внешний []
представляет собой набор. Коллекция используется для соответствия любому из символов, перечисленных внутри. Однако ведущий ^
отрицает совпадение. Таким образом, [abc123]
будет соответствовать a
, b
, c
, 1
, 2
или 3
, но [^abc123]
соответствует чему-либо, кроме этих символов.
-
[:space:]
- это класс символов. Классы символов могут использоваться только внутри коллекции. [:space:]
означает, что неудивительно, любые пробелы. В большинстве реализаций он напрямую связан с результатом функции библиотеки C isspace
.
Связывая все вместе, средство сбора данных "соответствует любому символу, который не является :
или пробелом".
-
\@=
- это положительное утверждение. Он применяется к предыдущему атому (в данном случае к коллекции) и означает, что коллекция требуется для успешного совпадения шаблона, но не будет частью замененного текста.
Итак, всякий раз, когда шаблон совпадает, мы просто заменяем :
на себя и на пробел.
Ответ 2
Вы хотите использовать отрицательное выражение с нулевой шириной, которое является причудливым способом сказать, что искать символ, а не пробел, но не включать его в соответствие:
:%s/: \@!/: /g
\@!
- отрицательный результат.
Ответ 3
Интересной особенностью регулярного выражения 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
соответствует позиции между двоеточием и чем-то не пространством.
Ответ 4
вы, вероятно, захотите использовать :[^ ]
для обработки всего, кроме пробелов. Как упоминалось Мэттом, это заставит вашу замену заменить дополнительный символ.
Есть несколько способов избежать этого, вот 2, которые я нахожу полезными.
1) Оборудуйте последнюю часть поискового запроса круглой скобкой \(\)
, это позволит вам ссылаться на ту часть поиска в вашем замещаемом ключе с помощью /1
.
Ваша окончательная строка замены должна выглядеть так:
%s/:\([^ ]\)/: \1/g
2) завершите поисковый запрос на раннем этапе с помощью \ze
. Это означает, что весь поиск должен выполняться для соответствия, но только часть до \ze
будет подсвечена/заменена
Ваша окончательная строка замены должна выглядеть так:
%s/:\ze[^ ]/: /g