In Vim, is there a way to search for lines that match say abc
but do not also contain xyz
later on the line? So the following lines would match:
The abc is the best The first three letters are abc
and the following would not match:
The abc is the best but xyz is cheaper The first three letters are abc and the last are xyz
I know about syntax like the following:
/abc\(xyz\)\@!
but that only avoids matching abcxyz
and not if there is anything in between, such as abc-xyz
. Using
/abc.*\(xyz\)\@!
also does not work because there are many positions later in the line where xyz
is not matched.
(I should note that on the command line I would do something like grep abc <infile | grep -v xyz
but I would like to do the above interactively in Vim.)
Negative lookahead That's a number \d+ , NOT followed by € . For that, a negative lookahead can be applied. The syntax is: X(?! Y) , it means "search X , but only if not followed by Y ".
Lookahead assertions are part of JavaScript's original regular expression support and are thus supported in all browsers.
Lookahead is used as an assertion in Python regular expressions to determine success or failure whether the pattern is ahead i.e to the right of the parser's current position. They don't match anything. Hence, they are called as zero-width assertions.
Zero-Width Matches As we've seen, a lookaround looks left or right but it doesn't add any characters to the match to be returned by the regex engine. Likewise, an anchor such as ^ and a boundary such as \b can match at a given position in the string, but they do not add any characters to the match.
Your attempt was pretty close; you need to pull the .*
that allows an arbitrary distance between the match and the asserted later non-match into the negative look-ahead:
/abc\(.*xyz\)\@!
I guess this works because the non-match is attempted for all possible matches of .*
, and only when all branches have been exhausted is the \@!
declared as fulfilled.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With