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?
- For the why part, see Why does my regular expression work in X but not in Y?Gilles 'SO- stop being evil'– Gilles 'SO- stop being evil'2014-05-04 21:05:32 +00:00Commented May 4, 2014 at 21:05
2 Answers
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" - 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– Gregg Leventhal2014-05-04 16:57:20 +00:00Commented May 4, 2014 at 16:57
- 7Also note the syntax for negativ lookbehind:
\@<!lanoxx– lanoxx2015-03-17 12:33:59 +00:00Commented Mar 17, 2015 at 12:33 - It goes with saying that you need to put the negative lookbehind before the pattern. An example:
\(some\)\@<!thingWill matchthingandeverythingandnothing, but notsomething.dwanderson– dwanderson2017-03-07 21:26:23 +00:00Commented Mar 7, 2017 at 21:26
(?!\.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).
- 1I think what regex library which
lessuses is depended on compiled time.cuonglm– cuonglm2014-05-04 18:32:11 +00:00Commented May 4, 2014 at 18:32 - @Gnouc, you're right, it even now supports PCRE it seems.Stéphane Chazelas– Stéphane Chazelas2014-05-05 06:04:28 +00:00Commented May 5, 2014 at 6:04
- Yeah, we can check if
lessusesPCREby parsing output ofldd $(which less). But with other library, do you know any way to check?cuonglm– cuonglm2014-05-05 06:11:04 +00:00Commented May 5, 2014 at 6:11 - 1@Gnouc, it prints the name of the regex library with
less --version.Stéphane Chazelas– Stéphane Chazelas2014-05-05 06:28:43 +00:00Commented May 5, 2014 at 6:28 - I use Ubuntu 12.04 LTS and with
less --verion, it only printsless 444along with Copyright.cuonglm– cuonglm2014-05-05 06:45:22 +00:00Commented May 5, 2014 at 6:45