in reply to Issue with matching regex

Hello KishKishore,

The variable $var1 contains the empty string, which matches any string (since any string, even the empty string itself, “contains” the empty string). That’s why the if block is executed.

15:58 >perl -wE "my $line = 'xyz'; my $var1 = ''; say 'Match' if $line + =~ /$var1/i;" Match 15:59 >

Hope that helps,

Athanasius <°(((><contra mundum סתם עוד האקר של פרל,

Replies are listed 'Best First'.
Re^2: Issue with matching regex
by choroba (Cardinal) on Oct 20, 2022 at 08:15 UTC
    It's even worse than that. When $var is emmpty, /$var/ matches anything only if there was no successful match before.

    E.g. if you prepend this at the beginning of the script:

    "abc" =~ /a/;

    it suddenly starts outputting "Outside if", because /$var/ runs the last successfully matched regex if there was any (see The empty pattern //). If you don't want this behaviour (and I bet you don't), never use a match with fully dynamic contents. You can change it to /(?:$var)/, so that the pattern doesn't get empty after interpolating the variable.

    Update: There probably should be a perlcritic policy forbidding a potentially empty regex match.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      The even better news is that the original if condition can be much simplified and by combining the first 2 regexen it can avoid the fully empty pattern into the bargain:

      if ($line =~ /$var1|$var2/i && $check =~ /YES/i) { print "Inside if\n" +;} else {print "Outside if\n";}

      Of course if we still have $var1 = '' then it will still match but that's a question for KishKishore as to what they actually intend.


      🦛

      Good point!
      So, e.g. by reversing the order of substatements inside the IF statement gives opposite result.
      if(($check =~ m/YES/i) and (($line =~ m/$var1/i) || ($line =~ m/$var2/ +i))) { print "Inside if\n";} else {print "Outside if\n";}
      ...unless ($check =~ m/Y/i) :)

      Thanks choroba,

      I didn’t know that! This special case must have been implemented for a reason, but I can’t think what it could have been.

      Using a non-capturing group to avoid this behaviour is a useful workaround.

      The good news is that this special case doesn’t seem to be present in Raku:

      23:48 >perl -wE "my $s = ''; say 'match1' if 'abc' =~ /b/; say 'match2 +' if 'adc =~ /(?:$s)/;" match1 match2 23:55 >perl -wE "my $s = ''; say 'match1' if 'abc' =~ /b/; say 'match2 +' if 'adc =~ /$s/;" match1 23:56 >raku -e "my Str $s = ''; say 'match1' if 'abc' ~~ /b/; say 'mat +ch2' if 'adc' ~~ /$s/;" match1 match2 23:56 >

      Cheers,

      Athanasius <°(((><contra mundum סתם עוד האקר של פרל,