СПРАВОЧНИК ПО VIM - Брам Мооленаар
Основные сведения о шаблонах представлены в разделе 03.9 руководства пользователя Vim. Более подробное объяснение также содержится в главе 27 руководства.
- Команды поиска
- Определение шаблона
- "Волшебный" синтаксис
- Обзор компонентов шаблонов
- Компоненты повтора
- Элементарные атомы
- Регистронезависимые шаблоны
- Сравнение с шаблонами Perl
- Подсветка обнаруженных соответствий
1. Команды поиска
При вводе шаблона поиска в тексте будет показано текущее соответствие, если опция 'incsearch' включена. Помните, что для перемещения курсора в отображаемую позицию, где найдено соответствие, необходимо завершить ввод команды поиска с помощью <CR>. Прервать ввод команды поиска можно с помощью <Esc>.
При включённой опции 'hlsearch' будут подсвечены все соответствия последнему использованному шаблону поиска. Временно отключить подсветку обнаруженных соответствий можно по команде |:nohlsearch|.
Указанные команды выполняют поиск соответствий заданному шаблону. Команды "/" и "?" позволяют также указывать дополнительное смещение для позиционирования курсора. Существует два типа смещений: построчное и посимвольное.
Vi не имеет посимвольных смещений.
Смещение задаёт позицию курсора относительно найденного соответствия:
[число] | заданное [число] строк ниже по тексту, в колонке 1 |
+[число] | заданное [число] строк ниже по тексту, в колонке 1 |
-[число] | заданное [число] строк выше по тексту, в колонке 1 |
e[+число] | заданное [число] символов справа от конца соответствия |
e[-число] | заданное [число] символов слева от конца соответствия |
s[+число] | заданное [число] символов справа от начала соответствия |
s[-число] | заданное [число] символов слева от начала соответствия |
b[+число] | то же, что и s[+число] (мнемоника: "begin", "начало") |
b[-число] | то же, что и s[-число] (мнемоника: "begin", "начало") |
Если в смещении указан знак '-' или '+', но [число] не указано, то по умолчанию используется значение 1. При использовании смещения с 'e', поиск становится включительным (иначе говоря, символ, на котором в итоге помещается курсор, будет включён в область, над которой производится операция).
Примеры:
шаблон | позиция курсора |
/проверка/+1 | на одну строку ниже слова "проверка", в колонке 1 |
/проверка/e | на символе 'а' в слове "проверка" |
/проверка/s+2 | на символе 'о' в слове "проверка" |
/проверка/b-3 | за три символа до слова "проверка" |
Если одна из таких команд применяется после оператора, то действию оператора будут подвергнуты символы, расположенные между позицией курсора до и после выполнения поиска. Однако, при использовании построчного смещения действие оператора выполняется над полными строками, заключёнными между позициями курсора до и после поиска.
Приведём пример выполнения поиска соответствий шаблону с последующей заменой найденного соответствия другими словами:
/цололо<CR> | найти "цололо" |
c//e | выполнить команду замены до конца найденного соответствия |
foo<Esc> | ввести текст для замены |
//<CR> | перейти к началу следующего соответствия |
c//e | выполнить команду замены до конца найденного соответствия |
bar<Esc> | ввести новый текст для замены |
и т.д. |
Особым смещением является ';', за которым следует новая команда поиска.
Например:
/test 1/;/test
/test.*/+1;?ing?
Первый пример позволяет найти первое соответствие слову "test", расположенное после первого соответствия шаблону "test 1".
Такая конструкция напоминает выполнение двух команд поиска одна за другой, за исключением следующих отличий:
- это может быть использовано в качестве единственной команды перемещения после оператора;
- направление выполнения последующей команды "n" или "N" зависит от направления поиска для первой команды;
- при возникновении ошибки курсор не перемещается вообще.
Шаблон и смещение, использованные для выполнения последнего поиска, запоминаются. Это можно использовать для повторения поиска, возможно в другом направлении или с другим числом-аргументом. Обратите внимание, что шаблоны, использованные в 'обычных' командах поиска, и шаблоны, использованные в команде замены текста ":s", запоминаются отдельно друг от друга. При выполнении поиска с пустым шаблоном применяется использованный раннее шаблон.
Значение опции 'magic' прилипает к последнему использованному шаблону. При изменении значения опции 'magic' смысл последнего использованного шаблона меняться не будет. В то же время, при изменении значения опции 'ignorecase' последний использованный шаблон может быть использован для обнаружения других соответствий в зависимости от нового значения этой опции.
Все соответствия последнему использованному шаблону подсвечиваются на экране, если включить опцию 'hlsearch'.
Чтобы очистить последний использованный шаблон, используйте команду
:let @/ = ""
Обратите внимание, что это не приводит к изменению значения шаблона на пустую строку, поскольку такому шаблону соответствовал бы абсолютно любой текст. В этом случае значение шаблона действительно очищается, возвращая редактор в состояние, в котором он находится в начале работы.
Команды поиска обычно пропускают соответствия, которые не приводят к перемещению курсора. Флаг 'c' в значении опции 'cpoptions' определяет, должно ли следующее соответствие быть найдено от следующего после позиции курсора символа или после такого пропущенного соответствия. См. также |cpo-c|.
с флагом 'c': "/..." переходит на 1-3 символа
без флага 'c': "/..." переходит на 1 символ
Непредсказуемость, возникающая при включённом флаге 'c', вызвана тем обстоятельством, что поиск начинается в первой колонке, пропуская соответствия до тех пор, пока не будет найдено следующее после позиции курсора соответствие.
В Vi команда ":tag" изменяет значение последнего использованного шаблона поиска, если выполняется поиск метки. В Vim этого не происходит: последний использованный шаблон для поиска по прежнему сохраняется в памяти, если флаг 't' не включён в значение опции 'cpoptions'. Шаблон поиска всегда помещается в историю поиска.
При включённой опции 'wrapscan' (по умолчанию), поиск может быть продолжен с другого конца буфера. Если опция 'wrapscan' выключена, то при поиске в обратном направлении выполнение команды поиска прекращается в начале файла, а при поиске в прямом направлении выполнение команды поиска прекращается в конце файла. Если опция 'wrapscan' включена, а соответствие шаблону не обнаружено, то выводится сообщение об ошибке "Шаблон не найден" и курсор не перемещается. При выключенной опции 'wrapscan' в такой ситуации выводится сообщение "поиск закончен в КОНЦЕ документа; ... не найдено" (при прямом направлении поиска) или "поиск закончен в НАЧАЛЕ документа; ... не найдено" (при обратном направлении поиска). Если поиск достигает конца документа при включённой опции 'wrapscan', то выводится сообщение "поиск будет продолжен с НАЧАЛА документа" или "поиск будет продолжен с КОНЦА документа" (при прямом или обратном направлении поиска соответственно). Вывод указанных сообщений может быть отменён путём включения флага 's' в значение опции 'shortmess'. При выводе указанных сообщений используется ситуация подсветки 'w' (по умолчанию: standout).
Вы не можете ограничить выполнение команды поиска "/" определённым диапазоном строк. Однако, вы можете использовать команду ":substitute" с флагом 'c' для достижения этой цели.
Например:
:.,300s/Шаблон//gc
Указанная команда выполняет поиск соответствия шаблону "Шаблон" от позиции курсора до строки 300. При обнаружении соответствия вам будет предложено ввести символ. Для прекращения поиска введите 'q', а для поиска следующего соответствия введите 'n'.
Команды "*", "#", "g*" и "g#" выполняют поиск соответствия слову, расположенному рядом с курсором в указанном ниже порядке. При этом используется первое найденное соответствие:
- Ключевое слово, находящееся в текущей позиции курсора.
- Первое ключевое слово, расположенное в той же строке справа от курсора.
- СЛОВО, находящееся в текущей позиции курсора.
- Первое СЛОВО, расположенное в той же строке справа от курсора.
Ключевое слово может состоять только из букв и символов, перечисленных в значении опции 'iskeyword'.
СЛОВО может быть составлено из любых непробельных символов (т.е. кроме символов табуляции <Tab> и пробелов <Space>).
Заметим, что если вы умеете печатать десятью пальцами, то эти команды очень легко запомнить: символ "#" находится под левым средним пальцем, а "*" под правым средним пальцем. По крайней мере так обстоит дело на обычной клавиатуре с латинскими символами.
2. Определение шаблона
Начинающим следует ознакомиться с главой 27 Руководства пользователя Vim.
-
Каждый шаблон состоит из одной или нескольких веток, разделённых символами "\|". Шаблону соответствуют любые строки, которые соответствуют одной из веток шаблона. Например, шаблону "цол\|оло" соответствуют строки "цол" и "оло". Если строка соответствует нескольким веткам, то используется первая ветка.
шаблон ::= ветка
или ветка \| ветка
или ветка \| ветка \| ветка
и т.д. -
Каждая ветка состоит из одной или нескольких склеек, соединённых символами "\&". Строка может соответствовать склейке в том случае, если она соответствует всем предыдущим склейкам в той же самой позиции. Примеры:
шаблону "цололо\&..." соответствует "цол" в строке "цололо".
шаблону ".*Петя\&.*Ваня" соответствует строка, содержащая слова "Петя"
и "Ваня"
ветка ::= склейка
или склейка \& склейка
или склейка \& склейка \& склейка
и т.д. -
Склейка состоит из одного и более элементов, расположенных друг за другом. Склейке соответствует строка, элементы которой последовательно соответствуют отдельным элементам склейки. Например, шаблону "f[0-9]b" соответствует строка, состоящая из "f", цифры и "b".
склейка ::= элемент
или элемент элемент
или элемент элемент элемент
и т.д. - Элемент состоит из атома, за которым может следовать указание на количество возможных повторений атома. Например, элементу "a*" соответствует любая последовательность, состоящая из нуля и более символов "a": "", "a", "aa", "aaa" и т.д. См. |/повтор|.
элемент ::= атом
или атом повтор - Атом может состоять из различных компонентов. Многим атомам соответствует только один символ текста. Такие атомы как правило являются одиночными обычными символами или классами символов. Скобки позволяют превращать в атомы другие шаблоны. Конструкция "\z(\)" используется только для подсветки синтаксиса.
атом ::= элементарный_атом |/элементарный_атом|
или \( шаблон \) |/\(|
или \%( шаблон \) |/\%(|
или \z( шаблон \) |/\z(|
3. "Волшебный" синтаксис
Некоторые символы в шаблонах рассматриваются как есть. Таким символам соответствуют буквально те же самые символы в тексте. Однако, если такие символы предваряются обратной косой чертой, то они приобретают особое значение.
Другие символы имеют специальное значение без использования обратной косой черты. Такие символы должны предваряться обратной косой чертой, чтобы восприниматься буквально.
Воспринимается тот или иной символ буквально или нет, зависит от значения опции 'magic' и перечисленных ниже элементов.
Использование "\m" в шаблоне позволяет рассматривать следующие далее компоненты шаблона так, как если бы была включена опция 'magic', вне зависимости от фактического значения этой опции. Использование "\M" приводит к тому, что следующие далее компоненты шаблона рассматриваются так, как если бы опция 'magic' была выключена.
Использование "\v" позволяет рассматривать все следующие в шаблоне символы ASCII, кроме '0'-'9', 'a'-'z', 'A'-'Z' и '_', как имеющие особое значение. Такой режим называется "очень волшебным".
Использование "\V" указывает, что из последующих символов только символ обратной косой черты имеет особое значение. Такой режим называется "очень неволшебным".
Примеры:
после: | \v | \m 'magic' |
\M 'nomagic' |
\V | соответствие |
$ | $ | $ | \$ | соответствует концу строки | |
. | . | \. | \. | соответствует любому символу | |
* | * | \* | \* | соответствует любому количеству повторений предыдущего атома | |
() | \(\) | \(\) | \(\) | группировка в атом | |
| | \| | \| | \| | выбор вариантов | |
\a | \a | \a | \a | алфавитный символ | |
\\ | \\ | \\ | \\ | обратная косая черта (буквально) | |
\. | \. | . | . | точка (буквально) | |
\{ | { | { | { | '{' (буквально) | |
a | a | a | a | 'a' (буквально) |
возможности \m, \M, \v и \V доступны только в Vim.
Рекомендуется всегда сохранять значение опции 'magic' равным значению по умолчанию, т.е. во включённом состоянии. Это позволяет избежать проблем с совместимостью. Чтобы сделать шаблон независимым от значения опции 'magic', поместите "\m" или "\M" в начале шаблона.
4. Обзор компонентов шаблонов
Обзор компонентов, используемых для указания повторения
Более подробное объяснение и примеры приводятся ниже, используйте гиперссылки.
повтор | количество соответствий предыдущему атому | |
'magic' | 'nomagic' | |
* | \* | 0 или более как можно больше |
\+ | \+ | 1 или более как можно больше (*) |
\= | \= | 0 или 1 как можно больше (*) |
\? | \? | 0 или 1 как можно больше (*) |
\{n,m} | \{n,m} | от n до m как можно больше (*) |
\{n} | \{n} | n в точности (*) |
\{n,} | \{n,} | не менее n как можно больше (*) |
\{,m} | \{,m} | от 0 до m как можно больше (*) |
\{} | \{} | 0 или более как можно больше (то же, что и *) (*) |
\{-n,m} | \{-n,m} | от n до m как можно меньше (*) |
\{-n} | \{-n} | n в точности (*) |
\{-n,} | \{-n,} | не менее n как можно меньше (*) |
\{-,m} | \{-,m} | от 0 до m как можно меньше (*) |
\{-} | \{-} | 0 или более как можно меньше (*) |
\@> | \@> | 1, как при соответствии целому шаблону (*) |
\@= | \@= | ничего, требует наличия соответствия (нулевая длина) (*) |
\@! | \@! | ничего, требует ОТСУТСТВИЯ соответствия (нулевая длина) (*) |
\@<= | \@<= | ничего, требует наличия предыдущего соответствия (нулевая длина) (*) |
\@<! | \@<! | ничего, требует ОТСУТСТВИЯ предыдущего соответствия (нулевая длина) (*) |
(*) Vi не имеет такой возможности.
Обзор элементарных атомов.
Более подробное объяснение и примеры приводятся ниже, используйте гиперссылки.
элементарный атом | атому соответствует | |
magic | nomagic | |
^ | ^ | начало строки (в начале шаблона) (нулевая длина) |
\^ | \^ | символ '^' |
\_^ | \_^ | начало строки (в любом месте шаблона) (нулевая длина) |
$ | $ | конец строки (в конце шаблона) (нулевая длина) |
\$ | \$ | символ '$' |
\_$ | \_$ | конец строки (в любом месте шаблона) (нулевая длина) |
. | \. | любой одиночный символ (кроме конца строки) |
\_. | \_. | любой одиночный символ или конец строки |
\< | \< | начало слова (нулевая длина) |
\> | \> | конец слова (нулевая длина) |
\zs | \zs | всё, что угодно, устанавливает начало соответствия |
\ze | \ze | всё, что угодно, устанавливает конец соответствия |
\%^ | \%^ | начало файла (нулевая длина) |
\%$ | \%$ | конец файла (нулевая длина) |
\%# | \%# | позиция курсора (нулевая длина) |
\%23l | \%23l | в строке 23 (нулевая длина) |
\%23c | \%23c | в колонке 23 (нулевая длина) |
\%23v | \%23v | в виртуальной колонке 23 (нулевая длина) |
Символьные классы
Vi не имеет такой возможности:
элементарный атом | атому соответствует | |
magic | nomagic | |
\i | \i | символ имени (см. справку по опции 'isident') |
\I | \I | то же, что и "\i", за исключением цифр |
\k | \k | символ ключевого слова (см. справку по опции 'iskeyword') |
\K | \K | то же, что и "\k", за исключением цифр |
\f | \f | символ имени файла (см. справку по опции 'isfname') |
\F | \F | то же, что и "\f", за исключением цифр |
\p | \p | печатный символ (см. справку по опции 'isprint') |
\P | \P | то же, что и "\p", за исключением цифр |
\s | \s | пробельный символ: <Space> и <Tab> |
\S | \S | непробельный символ; противоположность \s |
\d | \d | цифра: [0-9] |
\D | \D | не цифра: [^0-9] |
\x | \x | шестнадцатеричная цифра: [0-9A-Fa-f] |
\X | \X | не шестнадцатеричная цифра: [^0-9A-Fa-f] |
\o | \o | восьмеричная цифра: [0-7] |
\O | \O | не восьмеричная цифра: [^0-7] |
\w | \w | словарный символ: [0-9A-Za-z_] |
\W | \W | не словарный символ: [^0-9A-Za-z_] |
\h | \h | символ начала слова: [A-Za-z_] |
\H | \H | не символ начала слова: [^A-Za-z_] |
\a | \a | алфавитный символ: [A-Za-z] |
\A | \A | не алфавитный символ: [^A-Za-z] |
\l | \l | символ в нижнем регистре: [a-z] |
\L | \L | не символ в нижнем регистре: [^a-z] |
\u | \u | символ в верхнем регистре: [A-Z] |
\U | \U | не символ в верхнем регистре: [^A-Z] |
\_x | \_x | здесь x это любой из перечисленных выше символов: символьный класс, включающий символ конца строки |
(конец символьных классов)
элементарный атом | атому соответствует | |
magic | nomagic | |
\e | \e | <Esc> |
\t | \t | <Tab> |
\r | \r | <CR> |
\b | \b | <BS> |
\n | \n | конец строки |
~ | \~ | последняя заданная строка для замены текста |
\1 | \1 | строка, соответствующая первой группе \(\) Vi не имеет такой возможности. |
\2 | \2 | Как "\1", но для второй группы \(\) |
... | ||
\9 | \9 | Как "\1", но для девятой группы \(\) |
x | x | символ без особого значения соответствует сам себе |
[] | \[] | любой символ из перечисленных в скобках [] |
\%[] | \%[] | список атомов с необязательным соответствием |
\c | \c | регистронезависимое соответствие |
\C | \C | регистрозависимое соответствие |
\m | \m | включает опцию 'magic' для последующих символов шаблона |
\M | \M | отключает опцию 'magic' для последующих символов шаблона |
\v | \v | следующие далее символы являются "очень волшебными" |
\V | \V | следующие далее символы являются "очень неволшебными" |
\Z | \Z | игнорировать различия в "комбинированных символах" Unicode. Полезно при поиске текста на иврите или арабском с огласовками. |
Пример | соответствие |
\<\I\i* или \<\h\w* \<[a-zA-Z_][a-zA-Z0-9_]* |
Имя (например, в программе на языке C). |
\(\.$\|\. \) | Точка, за которой следует <EOL> или пробел. |
[.!?][])"']*\($\|[ ]\) | Шаблон поиска, который используется для обнаружения конца предложения почти с тем же определением, что и команда ")". |
cat\Z | Как "cat", так и "ca`t" ("a", за которым следует 0x0300). В то же время, "ca`t" (символ 0x00e0) этому шаблону не соответствует, несмотря на то, что они могут выглядеть одинаково. |
5. Компоненты повтора
Каждый атом может сопровождаться компонентом, указывающим сколько раз и каким образом данному атому может быть найдено соответствий. Такой компонент называется повтором. Обзор компонентов повтора приводится в разделе |/повтор|.
Невозможно использование повтора, которому может соответствовать несколько повторений атома, после атома, которому может соответствовать пустая строка. В противном случае это приводило бы к бесконечному циклу. При попытке использования такого повтора выводится сообщение об ошибке:
аргумент *, \+ или \{ может быть пустым
(при выключенной опции 'magic' используется \*) Указывает на 0 и более соответствий предыдущему атому. Используется максимально возможное количество соответствий.
Исключение: Если "*" используется в самом начале шаблона или сразу после "^", то ей соответствует символ звёздочки. Имейте в виду, что повторение "\_." может привести к тому, что шаблону будет соответствовать много текста, что может занять много времени для обработки. Например, шаблону "\_.*END" соответствует весь текст от текущей позиции курсора до последнего появления слова "END" в файле. Поскольку "*" соответствует максимально возможное количество появлений предшествующего атома, то при поиске соответствия происходит прежде всего пропуск всех строк вплоть до конца файла, а затем выполняется поиск "END", с посимвольным отступлением назад к позиции курсора. |
|||||||||||||||||||
Указывает на 1 и более соответствий предыдущему атому. Используется максимально возможное количество соответствий.
|
|||||||||||||||||||
Указывает на 0 или 1 соответствие предыдущему атому. Используется максимально возможное количество соответствий.
|
|||||||||||||||||||
\? | То же, что и \=. Не может быть использовано при обратном поиске по команде "?". Vi не имеет такой возможности. |
||||||||||||||||||
\{n,m} | Указывает на от n до m соответствий предыдущему атому. Используется максимально возможное количество соответствий. | ||||||||||||||||||
\{n} | Указывает на n соответствий предыдущему атому. | ||||||||||||||||||
\{n,} | Указывает на по крайней мере n соответствий предыдущему атому. Используется максимально возможное количество соответствий. | ||||||||||||||||||
\{,m} | Указывает на от 0 до m соответствий предыдущему атому. Используется максимально возможное количество соответствий. | ||||||||||||||||||
\{} | Указывает на 0 и более соответствий предыдущему атому. Используется максимально возможное количество соответствий (то же, что и *) | ||||||||||||||||||
\{-n,m} | Указывает на от n до m соответствий предыдущему атому. Используется минимально возможное количество соответствий. | ||||||||||||||||||
\{-n} | Указывает на n соответствий предыдущему атому. | ||||||||||||||||||
\{-n,} | Указывает на по крайней мере n соответствий предыдущему атому. Используется минимально возможное количество соответствий. | ||||||||||||||||||
\{-,m} | Указывает на от 0 до m соответствий предыдущему атому. Используется минимально возможное количество соответствий. | ||||||||||||||||||
\{-} | Указывает на 0 и более соответствий предыдущему атому. Используется минимально возможное количество соответствий. Vi не имеет этих возможностей. Здесь n и m это положительные десятичные целые числа. Если "-" указан немедленно после "{", то используется алгоритм первого самого короткого соответствия (см. пример ниже). В частности, "\{-}" работает так же, как и "*", но при этом используется алгоритм первого самого короткого соответствия. ОДНАКО: соответствие, которое начинается раннее, предпочитается самому короткому соответствию: шаблону "a\{-}b" соответствует "aaab" в строке "xaaab".
Символ } может предваряться необязательной обратной косой чертой: \{n,m\}. |
||||||||||||||||||
Соответствует предыдущему атому с нулевой длиной. Работает как "(?=шаблон)" в Perl.
При использовании "\@=" (или "^", "$", "\<", "\>") в соответствие не включается ни один символ. Эти компоненты нужны только для проверки возможности соответствия. Соответствие последующим компонентам выполняется в той же самой позиции. Последний из приведённых выше примеров не будет обнаруживать соответствия в "цололоцол", поскольку будет предпринята попытка обнаружить соответствие "цол" в той же позиции, что и "оло". Обратите внимание, что "\&" работает так же, как и использование "\@=": "цол\&.." это то же самое, что и "\(цол\)\@=..". Однако, применение "\&" проще, так как вам не требуется использовать скобки. |
|||||||||||||||||||
\@! | Соответствует ОТСУТСТВИЮ соответствия предыдущему атому в текущей позиции с нулевой длиной, см. (нулевая длина). Vi не имеет такой возможности. Работает как '(?!шаблон)" в Perl.
Трудность при использовании "\@!" заключается в том, что возможно множество мест, в которых отсутствует соответствие шаблону. "a.*p\@!" будет соответствовать текст от "a" до конца строки, поскольку ".*" могут соответствовать все символы строки, а "p" не соответствует конец строки. "a.\{-}p\@!" будут соответствовать "a", "ap", "aap" и т.д., за которыми не следует "p", поскольку "." может соответствовать "p", а после этого не может быть соответствий для "p\@!". Использовать "\@!" для поиска несоответствия до позиции соответствия не получится: "\(fцол\)\@!оло" будет соответствовать "цол" в "цололо", поскольку в той позиции, где имеется соответствие "оло", отсутствует соответствие "цол". Чтобы избежать соответствия для "цололо" можно использовать шаблон "\(цол\)\@!...оло", но ему не будет соответствовать "оло" в начале строки. Используйте "\(цол\)\@<!оло". |
||||||||||||||||||
Соответствует с нулевой длиной, если соответствие предыдущему атому заканчивается сразу перед тем, что следует за ним. (нулевая длина) Работает как '(?<=шаблон)" в Perl, однако Vim позволяет использовать шаблоны с различной длиной.
Для увеличения производительности лучше всего избегать использования данного компонента повтора. Попробуйте, например, вместо этого использовать "\zs" |/\zs|. Шаблон, которому соответствует то же, что и в предыдущем примере: an\_s\+\zsfile "\@<=" и "\@<!" проверяют соответствия в позиции, находящейся непосредственно перед тем, что следует далее.
|
|||||||||||||||||||
Соответствует с нулевой длиной, если предшествующему атому не соответствует то, что следует далее. Таким образом, соответствие этому компоненту происходит в том случае, если в текущей или предыдущей строке отсутствует позиция, в которой имеется такое соответствие атому, что оно заканчивается как раз перед тем, что следует далее. (нулевая длина) Работает как '(?<!шаблон)" в Perl, однако Vim позволяет использовать шаблоны с различной длиной. Соответствие предыдущему атому заканчивается непосредственно перед соответствием последующему компоненту, поэтому атом, заканчивающийся на ".*" будет работать. Предупреждение: этот компонент повтора может быть очень медленным (поскольку для установления соответствия должна быть выполнена проверка большого количества позиций).
|
|||||||||||||||||||
Соответствует предыдущему атому как при поиске соответствия всему шаблону. Работает как '(?>шаблон)" в Perl.
Этому компоненту соответствует предыдущий атом как если бы он сам по себе был шаблоном. Если соответствие не обнаружено, то повторный поиск с более короткими частичными соответствиями не производится. Например: и "a*b", и "a*ab" соответствует "aaab", но во втором случае "a*" соответствуют только первые два "a". "\(a*\)\@>ab" не будет соответствовать "aaab", поскольку "a*" соответствует "aaa" (максимально возможное количество "a"), поэтому "ab" соответствовать не будет. |
6. Элементарные атомы
Элементарным атомом может быть:
В начале шаблона или после "\|", "\(", "\%(" или "\n": соответствует началу строки.
|
|||||
\^ | Соответствует символу '^'. Может использоваться в любом месте шаблона. | ||||
Соответствует началу строки. (нулевая длина) Может использоваться в любом месте шаблона.
|
|||||
$ | В конце шаблона или перед "\|" или "\)" ("|" или ")" после "\v"): соответствует концу строки <EOL>. В других позициях соответствует символу '$'. (нулевая длина) | ||||
\$ | Соответствует символу '$'. Может использоваться в любом месте шаблона. | ||||
Соответствует концу строки, см. (нулевая длина). Может использоваться в любом месте шаблона. Обратите внимание, что шаблону "a\_$b" не будет соответствовать ни одна строка, поскольку "b" не может соответствовать конец строки. Используйте для этого "a\nb", см. |/\n|.
|
|||||
. (с опцией 'nomagic': \.) | Соответствует любому одиночному символу, кроме конца строки. | ||||
\_. | Соответствует любому одиночному символу или концу строки. Осторожно: "\_.*" соответствует всему тексту до конца буфера! | ||||
\< | Соответствует началу слова: следующий символ является первым символом слова. Словарные символы задаются значением опции 'iskeyword'. (нулевая длина) | ||||
\> | Соответствует концу слова: предыдущий символ является последним символом слова. Словарные символы задаются значением опции 'iskeyword'. (нулевая длина) | ||||
Задаёт начало соответствия в любой позиции: следующий символ является первым символом всего соответствия, см. (нулевая длина). Пример: /^\s*\zsif команда выполняет поиск "if" в начале строки, пробелы игнорируются. Пример: /\(.\{-}\zsFab\)\{3} команда выполняет поиск третьего соответствия "Fab". Vi не имеет такой возможности. |
|||||
\ze |
Задаёт конец соответствия в любой позиции: предыдущий символ является последним символом всего соответствия. (нулевая длина) Этот атом может быть использован неоднократно, используется последнее вхождение атома в ветке, где имеется соответствие. Пример: "end\ze\(if\|for\)" соответствует "end" в "endif" и "endfor". Vi не имеет такой возможности. |
||||
Соответствует началу файла. Если поиск соответствия происходит в строке, то соответствует началу строки. Например, чтобы найти первое появление "VIM" в файле: /\%^\_.\{-}\zsVIM |
|||||
Соответствует концу файла. Если поиск соответствия происходит в строке, то соответствует концу строки. /VIM\_.\{-}\%$ НЕ найдёт последнего появления слова "VIM" в файле: будет найдено следующее появление "VIM", поскольку следующий за ним компонент всегда будет иметь соответствие. Для поиска последнего появления "VIM" в файле необходимо использовать /VIM\ze\(\(VIM\)\@!\_.\)*\%$ В данном случае используется |/\@!|, чтобы убедиться, что соответствия "VIM" в какой-либо позиции после первого появления "VIM" не будет. Поиск от конца файла в обратном направлении может быть намного проще! |
|||||
Соответствует определённой позиции курсора. Работает только при поиске соответствий в буфере, отображённом в окне. ПРЕДУПРЕЖДЕНИЕ: Если курсор будет перемещён после использования данного компонента шаблона, то результат будет неправильным. Vim не выполняет автоматического обновления таких соответствий. Это особенно касается подсветки синтаксиса и работы опции 'hlsearch'. Другими словами, после перемещения курсора обновления экрана для изменения результата применения шаблона происходить не будет. Обновление производится в том случае, если строка будет изменена (тогда обновляется вся строка целиком), или по команде |CTRL-L| (обновляется весь экран). Например, для подсветки слова в позиции курсора: /\k*\%#\k* При включённой опции 'hlsearch' можете выполнить перемещение курсора и внести несколько изменений, чтобы увидеть, в каких случаях будет происходить автоматическое обновление. |
|||||
Соответствует заданной строке. Эти атомы могут быть использованы для поиска соответствий определённым строкам в буфере. "23" в приведённых примерах может быть любым номером строки. Первая строка имеет номер 1. ПРЕДУПРЕЖДЕНИЕ: После вставки или удаления строк Vim не выполняет автоматическое обновление соответствия. При использовании в подсветке синтаксиса могут возникнуть проблемы. Например, для подсветки строки, в которой находится курсор: :exe '/\%' . line(".") . 'l.*' При включённой опции 'hlsearch' можете выполнить перемещение курсора и внести несколько изменений, чтобы увидеть, в каких случаях будет происходить автоматическое обновление. |
|||||
Соответствует тексту в заданной колонке. Эти компоненты можно использовать для поиска соответствий определённым колонкам в буфере или строке. "23" в приведённых примерах может быть любым номером колонки. Первая колонка имеет номер 1. В действительности колонкой является номер байта в строке, так что в случае мультибайтных символов возможны расхождения. ПРЕДУПРЕЖДЕНИЕ: После вставки или удаления текста Vim не выполняет автоматическое обновление соответствия. При использовании в подсветке синтаксиса могут возникнуть проблемы. Например, для подсветки колонки, в которой находится курсор: :exe '/\%' . col(".") . 'c' При включённой опции 'hlsearch' можете выполнить перемещение курсора и внести несколько изменений, чтобы увидеть, в каких случаях будет происходить автоматическое обновление. Пример команды для включения в соответствие единственного байта в колонке 44: /\%>43c.\%<46c Обратите внимание, что шаблону "\%<46c" соответствует колонка 45, а "." соответствует байт в колонке 44. |
|||||
Соответствует тексту в заданной виртуальной колонке. Эти компоненты можно использовать для поиска соответствий определённым виртуальным колонкам в буфере или строке. Если поиск соответствия производится не в открытом в окне буфере, то используются значения опций (например, 'tabstop') для активного в данный момент окна. "23" в приведённых примерах может быть любым номером колонки. Первая колонка имеет номер 1. Обратите внимание, что некоторые позиции в виртуальных колонках никогда не будут включены в соответствие, если они находятся в середине символа табуляции или другого символа, занимающего несколько экранных символов. ПРЕДУПРЕЖДЕНИЕ: После вставки или удаления текста Vim не выполняет автоматическое обновление соответствия. При использовании в подсветке синтаксиса могут возникнуть проблемы. Например, для подсветки всех символов после виртуальной колонки 72: /\%>72v.* При включённой опции 'hlsearch' можете выполнить перемещение курсора и внести несколько изменений, чтобы увидеть, в каких случаях будет происходить автоматическое обновление. /.*\%17v Колонка 17 не будет включена в соответствие, потому что она задаёт позицию, где происходит соответствие шаблону "\%17v", а поскольку такое соответствие имеет нулевую длину (см. (нулевая длина)), то колонка 17 не включается в соответствие. Тех же результатов можно добиться при помощи шаблона /.*\%<18v |
Символьные классы:
Vi не имеет такой возможности.
ЗАМЕЧАНИЕ: вышеуказанные классы также работают с мультибайтными символами. Классы, указанные ниже работают только с символами ASCII, в соответствии с указанными диапазонами.
ЗАМЕЧАНИЕ: атомы работают быстрее, чем соответствующие диапазоны [].
ЗАМЕЧАНИЕ: Опция 'ignorecase', "\c" и "\C" не используются символьными классами.
\_x | где "x" является одним из указанных выше символов: Символьный класс с добавлением соответствия символу конца строки. |
(конец описания символьных классов)
7. Регистронезависимые шаблоны
При включённой опции 'ignorecase' регистр обычных символов не принимается во внимание. Опция 'smartcase' позволяет игнорировать регистр символов в тех случаях, когда в шаблоне содержатся только строчные буквы.
При появлении в шаблоне компонента "\c" весь шаблон рассматривается так, как если бы опция 'ignorecase' была включена. При этом действующие значения опций 'ignorecase' и 'smartcase' игнорируются. "\C" выполняет противоположную задачу: включает регистрозависимые соответствия для всего шаблона.
Только Vim поддерживает \c и \C.
Обратите внимание, что 'ignorecase', "\c" и "\C" не используются при работе с символьными классами.
Примеры:
шаблон | 'ignorecase' | 'smartcase' | соответствие |
foo | выкл. | - | foo |
foo | вкл. | - | foo Foo FOO |
Foo | вкл. | выкл. | foo Foo FOO |
Foo | вкл. | вкл. | Foo |
\cfoo | - | - | foo Foo FOO |
foo\C | - | - | foo |
Если в шаблоне появляется атом "\Z", то комбинированные символы игнорируются. В этом случае соответствие проверяется только для основного символа, в то время как акценты и их количество могут различаться. Это работает только в том случае, если значением опции 'encoding' является "utf-8".
Технические детали:
Символы <Nul> в файле хранятся в памяти в виде символов <NL>. При отображении на экране эти символы выглядят как "^@". Необходимые преобразования выполняются при чтении и записи файлов. Чтобы обнаружить соответствия символу <Nul> в шаблоне следует использовать CTRL-@ или "CTRL-V 000". Вероятнее всего, что именно такое поведение Vim вы и ожидаете. Внутри Vim указанные символы автоматически преобразуются в шаблоне поиска в символ <NL>. Необычным является то, что при вводе CTRL-V CTRL-J также происходит вставка символа <NL>, что позволяет искать символы <Nul> в файле.
Vi вообще не может работать с символами <Nul> в файле.
Если значением опции 'fileformat' является "mac", то символы <NL> в файле хранятся в памяти в виде символов <CR>. При отображении на экране эти символы выглядят как "^M". Во всех остальных отношениях поведение редактора схоже с описанным выше поведением при использовании <NL> вместо <Nul>.
При вычислении выражений символу <NL> в шаблоне соответствует символ <NL> в строке. Использование "\n" (обратная косая черта n) в шаблонах для передачи соответствия <NL> в таких случаях работать не будет: это применяется только при поиске соответствий тексту в буфере.
Шаблоны также могут работать с мультибайтными символами, однако при этом необходимо следить, чтобы в шаблоне не было неправильных байтов, иначе соответствие такому шаблону может быть не обнаружено.
8. Сравнение с шаблонами Perl
По своим возможностям шаблоны Vim очень похожи на шаблоны, используемые в Perl. Обычно различие между ними состоит только в синтаксисе; основные различия между ними представлены ниже:
Возможность | в Vim | в Perl |
насильная регистронезависимость | \c | (?i) |
насильная регистрозависимость | \C | (?-i) |
группировка без обратных ссылок | \%(атом) | (?:атом) |
минималистические повторы | \{-n,m} | *?, +?, ??, {}? |
соответствие с нулевой длиной | атом\@= | (?=атом) |
несоответствие с нулевой длиной | атом\@! | (?!атом) |
предшествующее соответствие с нулевой длиной | атом\@<= | (?<=атом) |
предшествующее несоответствие с нулевой длиной | атом\@<! | (?<!атом) |
соответствие без повторных попыток | атом\@> | (?>атом) |
Имеются различия в работе с символами новой строки внутри строк в Vim и Perl: В Perl соответствие ^ и $ по умолчанию работает только в самом начале и в самом конце текста, однако вы можете использовать флаг 'm', который позволяет также соответствовать границам строк внутри текста. Вы также можете использовать флаг 's', который позволяет использовать для поиска соответствий символу новой строки шаблон '.'. Оба флага можно устанавливать внутри шаблона, используя тот же синтаксис, что и для флага 'i', показанного выше.
С другой стороны, в Vim шаблонам ^ и $ всегда соответствуют символы новой строки, даже внутри текста. Имеются также два совершенно отдельных атома, \%^ и \%$, которым соответствует самое начало и самый конец текста. Вторая проблема решается в Vim при помощи "модификатора" \_: его можно поместить перед . или символьным классом, и тогда символы новой строки также будут соответствовать шаблону.
Наконец, следующие конструкции используются только в Perl:
- выполнение произвольного кода внутри регулярного выражения: (?{код perl})
- условные выражения: (?(условие)выражение_для_true|выражение_для_false)
...а эти конструкции применяются только в Vim:
- изменение "волшебных" свойств шаблона: \v \V \m \M (очень полезно для того, чтобы избежать нагромождения символов обратной косой черты)
- последовательность атомов, соответствие которым не обязательно: \%[атомы]
- \& (относится к \| как "и" относится к "или"; насильно устанавливает требование соответствия нескольким веткам в одном и том же месте)
- соответствие строкам/колонкам по их номеру: \%5l \%5c \%5v
- ограничение "возвращаемого значения" регулярного выражения: \zs \ze
9. Подсветка обнаруженных соответствий
:mat[ch] {группа} /{шаблон}/ |
Определяет шаблон, соответствия которому подсвечиваются в активном окне. Подсветка выполняется с помощью указанной {группы} подсветки. Например: :highlight MyGroup ctermbg=green guibg=green Вместо // для указания {шаблона} можно использовать любые парные символы, но необходимо следить, чтобы случайно не использовать спецсимволы типа '"' или '|'. Указанная {группа} должна существовать на момент выполнения команды. Найденные соответствия отменяют подсветку, выполненную при помощи опции 'hlsearch'. Опция 'ignorecase' не используется, но вы можете всегда включить в шаблон |/\c| для выполнения регистронезависимой подсветки. В противном случае выполняется регистрозависимая подсветка. Обратите внимание, что подсветка соответствий последнему использованному шаблону при помощи опции 'hlsearch' выполняется для всех открытых окон, в то время как соответствия шаблону, заданному при помощи команды ":match", используются только для подсветки в активном окне. Подсветка сохраняется при переключении между разными буферами. Ещё один пример, позволяющий выполнять подсветку всех символов в виртуальной колонке 72 и следующих за ними: :highlight rightMargin term=bold ctermfg=blue guifg=blue Для подсветки всех символов в виртуальной колонке 7: :highlight col8 ctermbg=grey guibg=grey Обратите внимание, что здесь используется два компонента, чтобы также поймать в соответствие символы, занимающие несколько виртуальных колонок, такие как TAB. |
:mat[ch] :mat[ch] none |
Очистить раннее использованный шаблон для подсветки соответствия. |