Negatywne asercje za / do przodu w Linux-ie mniej pager (lub vim)

14

Chcę znaleźć wszystkie wystąpienia „indeksu”, po których nie następuje .php w dzienniku za pomocą less. /index(?!\.php)nie działa. czy to możliwe? Co to jest regex dla less i vim (czy się różnią?). Czy nie jest to możliwe w przypadku bibliotek wyrażeń regularnych tych aplikacji?

Gregg Leventhal
źródło
Aby dowiedzieć się, dlaczego, zobacz Dlaczego moje wyrażenie regularne działa w X, ale nie w Y?
Gilles „SO- przestań być zły”

Odpowiedzi:

22

W vimmożesz zrobić tak:

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

Aby uzyskać więcej informacji, w trybie komend spróbuj :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
źródło
Piękny! Masz pomysł na mniej? To nie działa w mniejszym stopniu. Chciałbym, żeby zachowanie wyrażenia regularnego było wszędzie PCRE, ale niestety tak nie jest.
Gregg Leventhal
7
Zwróć także uwagę na składnię negatywnego lookbehind :\@<!
lanoxx
Rozumie się samo przez się mówi, że trzeba umieścić wygląd negatywny za wcześniej wzoru. Przykład: \(some\)\@<!thingdopasuje thingi everythinga nothing, ale nie something.
dwanderson
7

(?!\.php)jest operatorem regularnym perla. lesszazwyczaj używa systemowego wyrażenia regularnego POSIX, więc zwykle rozszerzone wyrażenia regularne GNU w systemie GNU vimużywają vimwyrażeń regularnych.

W vim, jak już pokazano przez cuonglm, odpowiednikiem index(?!\.php)byłoby index\(\.php\)\@!lub \vindex(\.php)@!.

W lessczasie kompilacji możesz wybrać bibliotekę wyrażeń regularnych / interfejs API, a tym samym typ wyrażeń regularnych do użycia:

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

Jednak domyślnie lessużyje POSIX-a regcompz REG_EXTENDED, więc otrzymasz rozszerzone wyrażenia regularne swojego systemu, więc zwykle coś podobnego jak z grep -E.

W rozszerzonym wyrażeniu regularnym GNU nie ma równoważnego spojrzenia za siebie ani operatora patrzenia w przyszłość.

Możesz to zrobić na własnej skórze:

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

Za lesspomocą &klawisza można ewentualnie odfiltrować wiersze zawierające index.php( &!index\.php), a następnie wyszukać index( /index). (nadal będziesz tęsknić za innymi przypadkami, indexktóre pojawiają się w wierszu zawierającym index.php).

Stéphane Chazelas
źródło
1
Myślę, że lessużywana biblioteka regex zależy od czasu kompilacji.
cuonglm
@Gnouc, masz rację, wydaje się, że nawet teraz obsługuje PCRE.
Stéphane Chazelas
Tak, możemy sprawdzić, czy lessużywa PCRE, analizując dane wyjściowe ldd $(which less). Ale czy w przypadku innej biblioteki znasz jakiś sposób na sprawdzenie?
cuonglm
1
@Gnouc, wypisuje nazwę biblioteki wyrażeń regularnych less --version.
Stéphane Chazelas
Używam Ubuntu 12.04 LTS, a dzięki less --veriondrukuje tylko less 444wraz z prawami autorskimi.
cuonglm