Регулярное выражение для вставки пространства в 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