all regex vim negative-lookahead

all - ¿Hay alguna manera de hacer una búsqueda negativa en vim regex?



vim replace %s (4)

Aunque su pregunta es sobre lookahead, la encontré mientras buscaba lookbind. Por lo tanto, publico la solución para mirar hacia atrás para que otros puedan encontrarla.

Si busca el pattern2 no precedido por el pattern1 , es decir, con un aspecto negativo, busque:

/(pattern1/)/@<!pattern2

En Vim, ¿hay una forma de buscar líneas que coincidan, por ejemplo, abc pero que no contengan xyz más adelante en la línea? Así que las siguientes líneas coincidirían:

The abc is the best The first three letters are abc

y lo siguiente no coincidiría:

The abc is the best but xyz is cheaper The first three letters are abc and the last are xyz

Sé de sintaxis como la siguiente:

/abc/(xyz/)/@!

pero eso solo evita emparejar abcxyz y no si hay algo en medio, como abc-xyz . Utilizando

/abc.*/(xyz/)/@!

Además, no funciona porque hay muchas posiciones más adelante en la línea donde xyz no coincide.

(Debo señalar que en la línea de comandos haría algo como grep abc <infile | grep -v xyz pero me gustaría hacer lo anterior de manera interactiva en Vim).


Creo que escribiría esto como /abc/(/(xyz/)/@!./)*$

No estoy seguro de si esto es más rápido que otras sugerencias (creo que podría ser ya que prueba cada posición solo una vez) pero tiene sentido conceptual como

"abc seguido de cualquier cosa que no sea xyz, cualquier número de veces hasta el final de la línea"

Me gusta más que "abc seguido de cualquier cosa no seguida de xyz" como en los otros patrones mencionados.


Esto funciona para mí /abc/(.*xyz/)/@!


Tu intento fue bastante cercano; necesita tirar del .* que permite una distancia arbitraria entre la partida y la no afirmada más tarde afirmada en el look-ahead negativo :

/abc/(.*xyz/)/@!

Supongo que esto funciona porque se intenta la no coincidencia para todas las coincidencias posibles de .* , Y solo cuando todas las ramas se han agotado es la /@! declarado como cumplido.