¿Es posible buscar en el sistema de expresiones regulares de vim?

22

Me he encontrado con muchas situaciones en vim donde sería útil tener declaraciones de búsqueda. He intentado usar la sintaxis de búsqueda estándar ( (?=), (?!)etc.) , pero parece que vim no lo admite. ¿Vim tiene una sintaxis equivalente para este tipo de declaraciones?

Árbol de hoja perenne
fuente

Respuestas:

29

Anclajes "Zoom"

Además de la respuesta de @ jecxjo, hay muchas situaciones en las que puede usar los anclajes de ancho cero \zsy en \zelugar de una búsqueda positiva. Estos anclajes definen el inicio ( \zs) y el final ( \ze) del partido dentro del patrón completo.

Ejemplos

  • foo\zsbarcoincidirá barprecedido por foo( foono forma parte del partido)
  • foo\zebarcoincidirá fooseguido de bar( barno parte del partido)
  • myFunction(\zs.*\ze)coincidirá con los parámetros en una llamada a la función (para fines de demostración, no me estoy centrando en la coincidencia codiciosa vs no codiciosa)

Poniéndolo a usar

Estos se vuelven más útiles cuando se utiliza el :substitutecomando. Por ejemplo, supongamos que quería reemplazar los parámetros en una llamada a la función myFunction()con foo:

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

Esto dejará myFunction(y )intacta, y no tiene que preocuparse por la captura de ellos en su patrón o repetirlos en su reemplazo .

Puede hacer esto usando la función de búsqueda de expresiones regulares de Vim, pero es bastante torpe:

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

(Creo que esta sintaxis me hace olvidar lo que estaba tratando de hacer en primer lugar).

Todavía necesitas mirar a veces

Todavía hay situaciones en las que necesita buscar. Utilizando \zsy \zeson excelentes para situaciones simples en las que tienes algo antes seguido de texto para que coincida seguido de algo después . Pero si es más complejo que eso, probablemente tendrá que atenerse a la sintaxis de aspecto más pesado.

Hecho de la diversión

¡Aunque son considerablemente más feos, las miradas de Vim son más poderosas que las de PCRE! Admiten mirar atrás negativamente de longitud variable, lo que significa que puede afirmar que algún patrón cuya longitud no está predeterminada no es anterior a su coincidencia.

PCRE no es compatible con esto, ya que es bastante computacionalmente costoso. Esa no es una gran preocupación en Vim, ya que los casos de uso más comunes de expresiones regulares tienden a involucrar búsquedas interactivas donde el tiempo de cálculo es casi imperceptible para el usuario. Sin embargo, probablemente lo notarías si se usara para resaltar la sintaxis.

Temas de ayuda relevantes

  • :help \zs
  • :help \ze
  • :help perl-patterns
tommcdo
fuente
No estaba al tanto de los anclajes de zoom. Gracias por explicarlos.
EvergreenTree
14

Parece que esto es posible. Hay una tabla simple para ir de 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)

Entonces, por ejemplo, si tiene la cadena one two threey desea coincidir onesolo si la <space>twosigue, puede usar

/one\(\stwo\)\@=

Esto es similar a la versión perl

m/one(?=\stwo)/
jecxjo
fuente