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