Asserções lookbehind / ahead negativas no Linux menos pager (ou vim)

14

Eu quero encontrar todas as instâncias de "índice" não seguidas por .php em um log usando less. /index(?!\.php)não funciona. Isso é possível? Qual é o regex para menos e vim (eles diferem?). Isso não é possível com as respectivas bibliotecas de expressões regulares do aplicativo?

Gregg Leventhal
fonte
Para a parte por que, consulte Por que minha expressão regular funciona em X, mas não em Y?
Gilles 'SO- stop be evil'

Respostas:

22

Em vim, você pode fazer assim:

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

Para mais detalhes, no modo de comando, tente :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
fonte
Lindo! Alguma ideia por menos? Isso não funciona em menos. Eu gostaria que o comportamento do regex fosse PCRE em todos os lugares, mas infelizmente não é.
Gregg Leventhal
7
Observe também a sintaxe para o negativo lookbehind :\@<!
lanoxx
É preciso dizer que você precisa deixar o olhar negativo para trás antes do padrão. Um exemplo: \(some\)\@<!thingirá corresponder thinge everythinge nothing, mas não something.
precisa saber é o seguinte
7

(?!\.php)é um operador perl regexp. lessgeralmente usa a API POSIX regexp do sistema, de modo que as expressões regulares estendidas do GNU em um sistema GNU vimusam vimexpressões regulares.

Em vim, como já mostrado por cuonglm, o equivalente a index(?!\.php)seria index\(\.php\)\@!ou \vindex(\.php)@!.

Pois less, em tempo de compilação, você pode escolher a biblioteca / API regex e, como resultado, o tipo de expressão regular a ser usado:

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

Por padrão, porém, lessusará o POSIX regcompcom REG_EXTENDED, para que você obtenha as expressões regulares estendidas do seu sistema, geralmente algo semelhante ao grep -E.

No regexp estendido do GNU, não há um operador equivalente para trás ou para frente.

Você poderia fazer da maneira mais difícil:

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

Com less, você pode usar a &tecla para filtrar as linhas que contêm index.php( &!index\.php) e depois procurar index( /index). (você ainda sentiria falta das outras instâncias indexque aparecem em uma linha que também contém index.php).

Stéphane Chazelas
fonte
1
Eu acho que a biblioteca regex que lessusa depende do tempo de compilação.
Cuonglm
@ Gnouc, você está certo, ele ainda suporta PCRE agora.
Stéphane Chazelas
Sim, podemos verificar se lessutiliza PCREanalisando a saída de ldd $(which less). Mas com outra biblioteca, você conhece alguma maneira de verificar?
cuonglm
1
@Gnouc, imprime o nome da biblioteca regex less --version.
Stéphane Chazelas
Eu uso o Ubuntu 12.04 LTS e less --verion, com , ele só imprime less 444junto com Copyright.
Cuonglm 5/05