Найти тему
Блокнот математика

Рубрика "Секреты Вим". Поиск и замена.

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

Если включена опция set incsearch (можно раз навсегда поместить в .vimrc или повесить на комбинацию клавиш через map или imap), то поиск идет по мере набирания выражения. А если включена опция set hls (highlight search), то все найденное будет подсвечено, пока подсветку не уберешь командой noh (и ее тоже можно повесить на какую-нибудь клавишу).

Поиск назад включается знаком вопроса. Повторить поиск в ту же сторону позволяет n, а в обратную --- N. С учетом повтора команды (точка .) и повтора замены &, получается мощный способ "найти и обработать".

Специальные поиски слова под курсором вперед (*) и назад (# ) удобнее, чем могут показаться.

Выражение поиска --- регулярное, о них много можно рассказывать. И расскажу в другой раз. Упомяну только, что \V позволяет выключить всю магию регэкспа и искать чистый текст. Это нужно нечасто, но бывает полезно: когда ищещь что-то со множеством квадратных скобок, точек и других символов. Второй --- когда составляешь сложные выражения.

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

С другой стороны, \v включает всю магию (и даже больше) и делает все символы, кроме a-z0-9_, особыми --- так даже в Перле не принято, разве что в шестом, который теперь зовется Raku.

По умолчанию, в Виме особый статус имеют: точка (любой символ), квадратные скобки (класс символов), ^ и $ --- начало и конец строки, * --- "нуль или более" и сам слеш. Поэтому "один или более" это не +, как в Перле, а \+

Еще малоизвестный ключ \c - он делает данный поиск регистронезависимым. А \C - зависимым. А без этих ключей можно включить зависимость от регистра опцией :ic (ignore case).

Для полноты напомню поиск символа в строке: f, F, t, T (вперед и назад, включительно и не включительно).

Так, f. - встанет на ближайшую точку справа, F. - слева, t. - перед ближайшей точкой справа, T. - после ближайшей точки слева.

Теперь замена

Для замены -служит всем известный оператор : s///

Действует только на строке. Если надо везде --- ставим перед ним % или диапазон (о диапазонах будет отдельная заметка). Например,

:s/Юля/Оля/

заменит первое вхождение имени Юля на Оля. Чтобы заменить все вхождения в строке, добавим g:

:s/Юля/Оля/g

А везде в тексте:

:%s/Юля/Оля/g

Простейший диапазон --- номера строк через запятую, точка --- текущая строка, $ - последняя.

Так что 1,$s - это то же, что и %s

После слеша стоит регулярное выражение для поиска, а после второго --- на что заменять. Все, что касается поиска, относится и к первому выражению.

В выражении замены особый статус у & --- "то, что нашлось", ~ --- прошлое выражение замены, слеш --- и всё.

Захватывающие скобки \( \) улавливают текст внутри них, который доступен в том же выражении или в строке замены по номеру открывающей скобки: \1, \2, ..., \9

Скобок может быть до девяти, так что \10 - это захват из первой скобки и потом нолик. Если реально надо больше девяти скобок, то используйте Перл --- там нет ограничений. Вот пример:

:%s/\<Юл\(\S\)\>/Ол\1/g

заменит вхожения Юля, Юлю, Юле и так далее --- после "Юл" идет непробельный символ (\S) --- на Оля, Олю, Оле и так далее: после "Ол" идет тот же символ, что в найденном. Он уловлен скобками \(\) и доступен как \1. Границы слова \< и \> исключают совпадения, например, с "Юлька". Их придется искать отдельно или сочинять выражение похитрее.

Еще полезны символы \U, \L, \E --- текст между \U и \E будет переведен в верхний регистр, а между \L и \E --- в нижний. В конце всего выражения \E можно и не ставить. Например,

:%s/\(\S\)ля/\U\1\Eля/g

заменит "юля" на Юля, а "оля" --- на Оля.

\u и \l меняют регистр одного символа, так можно капитализировать слова в заголовке, например: : s/\<\(\w*\)\>/\u\1/g

Так можно перевести то, что вы нашли, в нужный регистр. С учетом того, что & означает "то, что нашлось", можно легко делать довольно сложные вещи.

Наконец, в командном режиме символ & повторяет последнюю операцию поиска и замены.

Есть еще ключ /c --- он позволяет подтверждать каждую замену. То есть

:%s/X/Y/gc

не просто заменит X на Y, а позволит подтвердить каждую замену.

Можно, с опцией set hls, найти выражение --- все совпадения окажутся подсвечены --- посмотреть, все ли правильно, а потом запустить замену.

Наконец, ключ n не делает замену, а только считает число совпадений. Полезен для подсчета слов в тексте, например:

:%s/\<\S*\>//gn

Ищем полные слова (между границами \< и \> нет пробелов, нул или более символов), изем на всех строках (%) и все вхождения /g, замену (на ничего) не производим. В итоге увидим число слов.

:%s/\S//gn --- посчитаем непробельные символы.

:%s/.//gn --- посчитаем все символы.

Наконец, если опущено выражение поиска --- используется последнее использованное, а если опущено выражение замены --- то это удаление.

Вот такие возможности. Очень удобно! Реально очень удобно.