18

I want to find all instances of "index" not followed by .php in a log using less. /index(?!\.php) does not work. Is this possible? What is the regex for less and vim (do they differ?). Is this not possible with these application's respective regex libraries?

1

2 Answers 2

22

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" 
3
  • Beautiful! Any idea for less? This doesn't work in less. I wish regex behavior was PCRE everywhere, but alas it isn't. Commented May 4, 2014 at 16:57
  • 7
    Also note the syntax for negativ lookbehind: \@<! Commented Mar 17, 2015 at 12:33
  • It goes with saying that you need to put the negative lookbehind before the pattern. An example: \(some\)\@<!thing Will match thing and everything and nothing, but not something. Commented Mar 7, 2017 at 21:26
8

(?!\.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).

6
  • 1
    I think what regex library which less uses is depended on compiled time. Commented May 4, 2014 at 18:32
  • @Gnouc, you're right, it even now supports PCRE it seems. Commented May 5, 2014 at 6:04
  • Yeah, we can check if less uses PCRE by parsing output of ldd $(which less). But with other library, do you know any way to check? Commented May 5, 2014 at 6:11
  • 1
    @Gnouc, it prints the name of the regex library with less --version. Commented May 5, 2014 at 6:28
  • I use Ubuntu 12.04 LTS and with less --verion, it only prints less 444 along with Copyright. Commented May 5, 2014 at 6:45

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.