Linux less pager(或vim)中的负面回顾/超前断言

Gre*_*hal 16 less vim regular-expression

我想在使用 .php 的日志中找到所有没有跟在 .php 后面的“索引”实例less/index(?!\.php)不起作用。这可能吗?less 和 vim 的正则表达式是什么(它们有区别吗?)。这些应用程序各自的正则表达式库无法做到这一点吗?

cuo*_*glm 22

在 中vim,您可以这样做:

/index\(\.php\)\@!
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请在命令模式下尝试: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"
Run Code Online (Sandbox Code Playgroud)

  • 还要注意 **negativ lookbehind** 的语法:`\@<!` (7认同)

Sté*_*las 7

(?!\.php)是一个 perl 正则表达式运算符。less通常使用系统的 POSIX regexp API,因此 GNU 系统上的 GNU 扩展正则表达式通常vim使用vim正则表达式。

在 中vim,正如 cuonglm 已经表明的那样,相当于index(?!\.php)将是index\(\.php\)\@!\vindex(\.php)@!

对于less,在编译时,您可以选择正则表达式库/API,从而选择要使用的正则表达式类型:

    --with-regex={auto,gnu,pcre,posix,regcmp,re_comp,
                    regcomp,regcomp-local,none}
        Select a regular expression library  auto
Run Code Online (Sandbox Code Playgroud)

但默认情况下,less将使用regcomp带有 REG_EXTENDED 的POSIX ,因此您将获得系统的扩展正则表达式,因此通常类似于grep -E.

在 GNU 扩展的正则表达式中,没有等效的后视或前视运算符。

你可以用困难的方式做到:

index($|[^.]|\.($|([^p]|p($|([^h]|h($|[^p]))))))
Run Code Online (Sandbox Code Playgroud)

使用less,您可以使用&关键字过滤掉包含index.php( &!index\.php)的行,然后搜索index( /index)。(您仍然会错过index出现在也包含 的行上的其他实例index.php)。