Why is this negative lookbehind being considered a successful regex match?

negative-lookbehind, perl, regex

Solution

You have the position of the negative lookback assertion backwards.

It is zero width, so needs to be in front of the `y` as you have written it.

Given:

$ echo $'xy\nay\nyx' 
xy
ay
yx

The lookbehind `/y(?<!x)/` matches lines with `x` in front or in back of `y` because `y` is behind the assertion (not `x`):

$ echo $'xy\nay\nyx' | perl -n -e 'print if /y(?<!x)/'
xy
ay
yx

Note that `yx` also matches since the assertion comes prior to `x` and is looking at `y` so all three lines are matches.

Vs what you are looking for:

$ echo $'xy\nay\nyx' | perl -n -e 'print if /(?<!x)y/'
ay
yx

Demo

Further explanation.

Or, you need to account for width of the `y` (or whatever the match is) if looking backwards after the `y` by including the `y` in the assertion:

$ echo $'xy\nay\nyx' | perl -n -e 'print if /y(?<!xy)/'
ay
yx

Problem

I would expect that this simple text string would not be considered a match: ``` xyz@xyz:~$ echo xy | perl -n -e 'print if /y(?<!x)/' xy ``` But strangely enough it is. I've tried it also @ https://regex101.com/ and the result is the same. It seems like it will match the `y`, which confuses me. If my understanding is correct, the above regex should only match `y`s that are not preceded by a `x`. PS: I gave this a simplistic example. In general I would like to use negative lookbehinds to match against full strings and not necessarily single characters such as x. I'm using the Perl regex flavour. Thanks

Original source