Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 ys 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

like image 545
devoured elysium Avatar asked Dec 23 '22 18:12

devoured elysium


1 Answers

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
like image 109
dawg Avatar answered Dec 27 '22 11:12

dawg