Negative lookahead assertion with the * modifier in Perl

perl, regex, regex-lookarounds

Solution

It matches because zero is included in "any number". So no spaces, followed by a space, matches "any number of spaces not followed by a Q".

You should add another lookahead assertion that the first thing after your spaces is not itself a space. Try this (untested):

 <@> *(?!QQQ)(?! )

ETA Side note: changing the quantifier to + would have helped only when there's exactly one space; in the general case, the regex can always grab one less space and therefore succeed. Regexes want to match, and will bend over backwards to do so in any way possible. All other considerations (leftmost, longest, etc) take a back seat - if it can match more than one way, they determine which way is chosen. But matching always wins over not matching.

Problem

I have the (what I believe to be) negative lookahead assertion `<@> *(?!QQQ)` that I expect to match if the tested string is a `<@>` followed by any number of spaces (zero including) and then not followed by `QQQ`. Yet, if the tested string is `<@> QQQ` the regular expression matches. I fail to see why this is the case and would appreciate any help on this matter. Here's a test script ``` use warnings; use strict; my @strings = ('something <@> QQQ', 'something <@> RRR', 'something <@>QQQ' , 'something <@>RRR' ); print "$_\n" for map {$_ . " --> " . rep($_) } (@strings); sub rep { my $string = shift; $string =~ s,<@> *(?!QQQ),at w/o ,; $string =~ s,<@> *QQQ,at w/ QQQ,; return $string; } ``` This prints ``` something <@> QQQ --> something at w/o QQQ something <@> RRR --> something at w/o RRR something <@>QQQ --> something at w/ QQQ something <@>RRR --> something at w/o RRR ``` And I'd have expected the first line to be `something <@> QQQ --> something at w/ QQQ`.

Original source