È possibile cercare il sistema regex di vim?


22

Ho riscontrato molte situazioni in vim in cui sarebbe utile avere dichiarazioni lookaround. Ho provato a utilizzare la sintassi standard ( (?=), (?!)ecc.) , Ma sembra che VIM non supporti questo. Vim ha una sintassi equivalente per questo tipo di affermazioni?

Risposte:


29

Ancoraggi "Zoom"

Oltre alla risposta di @ jecxjo, ci sono molte situazioni in cui è possibile utilizzare gli ancoraggi di larghezza zero \zse \zeinvece di lookaround positivo. Queste ancore definiscono l'inizio ( \zs) e la fine ( \ze) della corrispondenza all'interno del modello completo.

Esempi

  • foo\zsbarcorrisponderà barpreceduto da foo( foonon parte della partita)
  • foo\zebarcorrisponderà fooseguito da bar( barnon parte della partita)
  • myFunction(\zs.*\ze)corrisponderà ai parametri in una chiamata di funzione (a scopo dimostrativo, non mi sto concentrando sulla corrispondenza avida vs non avida)

Mettendolo in uso

Questi diventano più utili quando si utilizza il :substitutecomando. Ad esempio, supponiamo che volessi sostituire i parametri in una chiamata di funzione myFunction()con foo:

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

Questo lascerà myFunction(e sarà )intatto e non dovrai preoccuparti di catturarli nel tuo schema o di ripeterli nella tua sostituzione .

Puoi farlo usando la funzionalità di lookgeund della regex di Vim, ma è piuttosto goffa:

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

(Trovo che questa sintassi mi faccia dimenticare in primo luogo quello che stavo cercando di fare.)

Hai ancora bisogno di lookaround a volte

Ci sono ancora situazioni in cui hai bisogno di cercare. Usare \zse \zeè ottimo per situazioni semplici in cui hai qualcosa prima seguito da un testo da abbinare seguito da qualcosa dopo . Ma se è più complesso di quello, probabilmente dovrai attenersi alla sintassi di lookaround più pesante.

Fatto divertente

Sebbene siano considerevolmente più brutti, i lookaround di Vim sono più potenti di quelli in PCRE! Supportano un aspetto negativo a lunghezza variabile, il che significa che puoi affermare che un modello la cui lunghezza non è predeterminata non è precedente alla tua corrispondenza.

PCRE non lo supporta, poiché è abbastanza costoso dal punto di vista computazionale. Non è una grande preoccupazione in Vim, poiché i casi d'uso più comuni di regex tendono a coinvolgere la ricerca interattiva in cui il tempo di calcolo è quasi impercettibile per l'utente. Probabilmente lo noteresti se fosse usato per l'evidenziazione della sintassi, però.

Argomenti della Guida pertinenti

  • :help \zs
  • :help \ze
  • :help perl-patterns

Non ero a conoscenza delle ancore di zoom. Grazie per averli spiegati.
EvergreenTree

14

Sembra che sia possibile. C'è una semplice tabella per passare da perl a 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)

Quindi, ad esempio, se hai la stringa one two threee vuoi abbinarla onesolo se la <space>twosegui, puoi usarla

/one\(\stwo\)\@=

Questo è simile alla versione perl

m/one(?=\stwo)/
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.