Возможен ли поиск в системе регулярных выражений vim?

22

Я столкнулся со многими ситуациями в vim, где было бы полезно иметь обходные утверждения. Я попытался использовать стандартный синтаксис lookaround ( (?=)и (?!)т. Д.) , Но, похоже, vim не поддерживает это. Имеет ли vim эквивалентный синтаксис для таких операторов?

Вечнозеленое дерево
источник

Ответы:

29

"Zoom" якоря

В дополнение к @ jecxjo отвечают, есть много ситуаций , в которых можно использовать в нулевой ширины якоря \zsи \zeвместо положительного lookaround. Эти привязки определяют начало ( \zs) и конец ( \ze) совпадения в полном шаблоне.

Примеры

  • foo\zsbarбудет соответствовать barпредшествует foo( fooне является частью матча)
  • foo\zebarбудет соответствовать с fooпоследующим bar( barне является частью матча)
  • myFunction(\zs.*\ze)будет соответствовать параметрам в вызове функции (в демонстрационных целях я не фокусируюсь на сопоставлении с жадным алгоритмом или без сопоставления)

Положить его на использование

Они становятся наиболее полезными при использовании :substituteкоманды. Так , например, сказать , что я хотел , чтобы заменить параметры в вызове функции , чтобы myFunction()с foo:

:%s/myFunction(\zs.*\ze)/foo/

Это оставит myFunction(и )нетронутое, и вам не придется беспокоиться о захвате их в шаблоне или повторять их в замене .

Вы можете сделать это, используя особенность регулярных выражений Vim, но это довольно неуклюже:

:%s/\(myFunction(\)\@<=.*\()\)\@=/foo/

(Я считаю, что этот синтаксис заставляет меня забыть, что я пытался сделать в первую очередь.)

Вы все еще иногда нуждаетесь в уходе

Есть еще ситуации, когда нужно искать обходной путь. Использование \zsи \zeотлично подходит для простых ситуаций, когда у вас есть что-то перед тем, как следовать тексту, после чего следует что-то после . Но если это сложнее, вам, вероятно, придется придерживаться более сложного синтаксиса.

Забавный факт

Несмотря на то, что они выглядят значительно хуже, взгляды Vim более мощные, чем в PCRE! Они поддерживают отрицательный внешний вид переменной длины, что означает, что вы можете утверждать, что некоторый шаблон, длина которого не определена, находится не перед вашим соответствием.

PCRE не поддерживает это, поскольку это довольно дорого в вычислительном отношении. В Vim это не большая проблема, так как наиболее распространенные случаи использования регулярных выражений, как правило, включают интерактивный поиск, когда время вычислений практически незаметно для пользователя. Вы, вероятно, заметите это, если использовать его для подсветки синтаксиса.

Соответствующие разделы справки

  • :help \zs
  • :help \ze
  • :help perl-patterns
tommcdo
источник
Я не знал о якорях зума. Спасибо за объяснение их.
EvergreenTree
14

Похоже, это возможно. Существует простая таблица для перехода от perl к vim.:h perl-patterns

9. Compare with Perl patterns               *perl-patterns*

Vim's regexes are most similar to Perl's, in terms of what you can do.  The
difference between them is mostly just notation;  here's a summary of where
they differ:

Capability                  in Vimspeak   in Perlspeak
----------------------------------------------------------------
force case insensitivity    \c            (?i)
force case sensitivity      \C            (?-i)
backref-less grouping       \%(atom\)     (?:atom)
conservative quantifiers    \{-n,m}       *?, +?, ??, {}?
0-width match               atom\@=       (?=atom)
0-width non-match           atom\@!       (?!atom)
0-width preceding match     atom\@<=      (?<=atom)
0-width preceding non-match atom\@<!      (?<!atom)
match without retry         atom\@>       (?>atom)

Так, например, если у вас есть строка, one two threeи вы хотите сопоставить oneтолько если <space>twoследует, вы можете использовать

/one\(\stwo\)\@=

Это похоже на версию Perl

m/one(?=\stwo)/
jecxjo
источник