Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question
    
For the why part, see Why does my regular expression work in X but not in Y? –  Gilles May 4 at 21:05

2 Answers 2

up vote 3 down vote accepted

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"
share|improve this answer
    
Beautiful! Any idea for less? This doesn't work in less. I wish regex behavior was PCRE everywhere, but alas it isn't. –  Gregg Leventhal May 4 at 16:57

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

share|improve this answer
1  
I think what regex library which less uses is depended on compiled time. –  Gnouc May 4 at 18:32
    
@Gnouc, you're right, it even now supports PCRE it seems. –  Stéphane Chazelas May 5 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? –  Gnouc May 5 at 6:11
    
@Gnouc, it prints the name of the regex library with less --version. –  Stéphane Chazelas May 5 at 6:28
    
I use Ubuntu 12.04 LTS and with less --verion, it only prints less 444 along with Copyright. –  Gnouc May 5 at 6:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.