Aserciones negativas de mirar hacia atrás / adelante en Linux menos buscapersonas (o vim)

14

Quiero encontrar todas las instancias de "índice" no seguidas por .php en un registro usando less. /index(?!\.php)No funciona. es posible? ¿Cuál es la expresión regular para less y vim (¿difieren?). ¿No es esto posible con las bibliotecas de expresiones regulares respectivas de estas aplicaciones?

Gregg Leventhal
fuente
Para la parte de por qué, vea ¿Por qué mi expresión regular funciona en X pero no en Y?
Gilles 'SO- deja de ser malvado'

Respuestas:

22

En vim, puedes hacer así:

/index\(\.php\)\@!

Para más detalles, en modo comando, intente :h \@:

\@!     Matches with zero width if the preceding atom does NOT match at the
        current position. /zero-width {not in Vi}
        Like '(?!pattern)" in Perl.
        Example                 matches
        foo\(bar\)\@!           any "foo" not followed by "bar"
        a.\{-}p\@!              "a", "ap", "aap", "app", etc. not immediately
                                followed by a "p"
        if \(\(then\)\@!.\)*$   "if " not followed by "then"
Cuonglm
fuente
¡Hermosa! ¿Alguna idea por menos? Esto no funciona en menos. Desearía que el comportamiento regex fuera PCRE en todas partes, pero por desgracia no lo es.
Gregg Leventhal
77
También tenga en cuenta la sintaxis para mirar atrás negativ :\@<!
lanoxx
Va con decir que debes dejar atrás la mirada negativa antes del patrón. Un ejemplo: \(some\)\@<!thingcoincidirá con thingy everythingy nothing, pero no something.
dwanderson
7

(?!\.php)es un operador perge regexp. lessgeneralmente usa la API de expresión regular POSIX del sistema, por lo que generalmente las expresiones regulares extendidas de GNU en un sistema GNU vimusan vimexpresiones regulares.

En vim, como ya se muestra por cuonglm, el equivalente de index(?!\.php)sería index\(\.php\)\@!o \vindex(\.php)@!.

Para less, en el momento de la compilación, puede elegir la biblioteca / API de expresiones regulares y, como resultado, el tipo de expresiones regulares que se utilizará:

    --with-regex={auto,gnu,pcre,posix,regcmp,re_comp,
                    regcomp,regcomp-local,none}
        Select a regular expression library  auto

Sin embargo, de manera predeterminada, lessusará POSIX regcompcon REG_EXTENDED, por lo que obtendrá las expresiones regulares extendidas de su sistema, por lo que generalmente es algo similar a con grep -E.

En GNU Extended regexp, no hay un operador equivalente de mirar hacia atrás o mirar hacia adelante.

Podrías hacerlo de la manera difícil:

index($|[^.]|\.($|([^p]|p($|([^h]|h($|[^p]))))))

Con less, posiblemente podría usar la &tecla para filtrar las líneas que contienen index.php( &!index\.php) y luego buscar index( /index). (aún extrañaría las otras instancias indexque aparecen en una línea que también contiene index.php).

Stéphane Chazelas
fuente
1
Creo que la biblioteca de expresiones regulares que lessutiliza depende del tiempo compilado.
Cuonglm
@Gnouc, tienes razón, parece que incluso ahora es compatible con PCRE.
Stéphane Chazelas 05 de
Sí, podemos verificar si se lessusa PCREanalizando la salida de ldd $(which less). Pero con otra biblioteca, ¿conoce alguna forma de verificar?
Cuonglm 05 de
1
@Gnouc, imprime el nombre de la biblioteca de expresiones regulares con less --version.
Stéphane Chazelas 05 de
Yo uso Ubuntu 12.04 LTS y con less --verion, solo imprime less 444junto con Copyright.
Cuonglm 05 de