Negative lookbehind/ahead assertions in Linux less pager (or vim)

In vim, you can do like this:

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

For more details, in command mode, try :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"

(?!\.php) is a perl regexp operator. less generally uses the system's POSIX regexp API, so typically GNU extended regular expressions on a GNU system, vim uses vim regular expressions.

In vim, as already shown by cuonglm, the equivalent of index(?!\.php) would be index\(\.php\)\@! or \vindex(\.php)@!.

For less, at compile time, you can choose the regex library/API and as a result the regex type to use:

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

By default though, less will use POSIX regcomp with REG_EXTENDED, so you'll get the extended regular expressions of your system, so typically something similar as with grep -E.

In GNU extended regexp, there's no equivalent look behind or look ahead operator.

You could do it the hard way:

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

With less, you could possibly use the & key to filter out the lines containing index.php (&!index\.php), and then search for index (/index). (you'd still miss the other instances of index that appear on a line also containing index.php).