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