Reply to message «How to match A but not B», 
sent 23:58:07 27 April 2011, Wednesday
by howard Schwartz:

> /^\%(.*PPD\)\@!.*DEBIT
In this case it will process regex inside `\%(...\)' as usual, but will reject 
the position if it matches.

> I was aware of \@!, but the documention warned that .* will match
> everything including PPD, before the pattern can find PPD and exclude it.
> That is why one must know something about where a string is, to exclude it
> in a pattern match, no?
It is not applicable for the case when `.*' is inside `\@!': regex inside `\@!' 
is processed as any other regex, the effect of `\@!' is that position is 
discarded if it matches. So when `.*' is inside negative lookahead group, regex 
engine will try to rollback until it finds `PPD', just like it will do with 
`/^.*PPD/'. If it is outside, regex engine won't have any reasons to rollback.

> /^DEBIT.*\%(PPD\)\@!/
In this case it will first process `DEBIT.*' and only then check `PPD'. Of 
course it won't match as `.*' consumed all non-newlines. You should use 
`/^DEBIT\%(.*PPD\)\@!/' here.

>       Using "\@!" is tricky, because there are many places where a pattern
>       does not match.  "a.*p\@!" will match from an "a" to the end of the
>       line, because ".*" can match all characters in the line and the "p"
>       doesn't match at the end of the line.
> 
> Also the order seems wrong to me, but maybe this does not matter? The
> string, DEBIT always occrs at the beginning of the line, if it occurs at
> all, and the string, PPD always occurs after DEBIT, if it occurs at all.
What order? I do not see anything wrong.

> Would the pattern not be:
>
> /^DEBIT.*\%(PPD\)\@!/
> 
> And then there is the problem that .* will match PPD before the exclude
> operator \@! can exclude it?
You are right and `a.*p\@!' is same as `a.*\%(p\)\@!', but it is not an exclude 
operator. It is negative look-ahead which means `discard position if pattern 
matches'. Correct regex is `/\v^DEBIT%(.{-}PPD)@!/' (`{-}' should be a bit 
faster as it will eliminate the reason to rollback).

Original message:
> Benjamen suggested:
> 
> /^\%(.*PPD\)\@!.*DEBIT
> 
> I was aware of \@!, but the documention warned that .* will match
> everything including PPD, before the pattern can find PPD and exclude it.
> That is why one must know something about where a string is, to exclude it
> in a pattern match, no?
> 
> To quote the documentation:
> 
>       Using "\@!" is tricky, because there are many places where a pattern
>       does not match.  "a.*p\@!" will match from an "a" to the end of the
>       line, because ".*" can match all characters in the line and the "p"
>       doesn't match at the end of the line.
> 
> Also the order seems wrong to me, but maybe this does not matter? The
> string, DEBIT always occrs at the beginning of the line, if it occurs at
> all, and the string, PPD always occurs after DEBIT, if it occurs at all.
> Would the pattern not be:
> 
> /^DEBIT.*\%(PPD\)\@!/
> 
> And then there is the problem that .* will match PPD before the exclude
> operator \@! can exclude it?

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to