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


22

Я стикався з багатьма ситуаціями в vim, коли було б корисно мати орієнтовні заяви. Я спробував з допомогою стандартного синтаксису lookaround ( (?=), і (?!)так далі ..) , але це , здається ВІМ не підтримує це. Чи має vim еквівалентний синтаксис для таких типів висловлювань?

Відповіді:


29

"Збільшити" якорі

Окрім відповіді @ jecxjo, існує багато ситуацій, коли можна використовувати якорі нульової ширини \zsта \zeзамість позитивного пошуку. Ці якорі визначають початок ( \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

Я не знав про якір для збільшення. Дякуємо, що пояснили їх.
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)/
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.