in reply to Regular Expression gotchas ?

Thus the following command is evaluated regardless of filename:
$error ||= "Unexpected signer 'GOODSIG 86125876138571635 ClientKey' is + not ''." unless ('GOODSIG 86125876138571635 ClientKey' =~ m/\Q\E/);
yet sometimes an error is created, sometimes not.

If the error is created, that's because it is set elsewhere. The code you gave will not change $error when $expected_signer is an empty string. That's because m/\Q$foo\E/ will match anything when $foo is empty. (Every string contains an empty string.) In this snippet, $error is only set unless the match is true. Since it is true, $error isn't set.

Update: Changed "Every string matches an empty string" to "Every string contains an emptry string." The latter is what I really meant (as the context implies.) My thanks go to Enlil for spotting it.

-sauoq
"My two cents aren't worth a dime.";

Replies are listed 'Best First'.
Re: Re: Regular Expression gotchas ?
by the_Don (Scribe) on Feb 17, 2003 at 08:13 UTC

    Please run the code below and see if you get the same output as I do (also below). If so, I would like to know why it is behaving as it is.

    #!/usr/local/perl -w use strict; my $filename1 = 'FILE.pgp'; my $filename2 = 'FILE.gpg'; my $signer = 'Some person <someone@this.com>'; my $exp_sender= ''; my $new_filename1 = $filename1; $new_filename1 =~ s/(\.gpg)|(\.encrypted)/\.decrypted/; print ".PGP FILE ERROR:'$signer' is not '$exp_sender'.\n" unless ($signer =~ m/\Q$exp_sender\E/); my $new_filename2 = $filename2; $new_filename2 =~ s/(\.gpg)|(\.encrypted)/\.decrypted/; print ".GPG FILE ERROR:'$signer' is not '$exp_sender'.\n" unless ($signer =~ m/\Q$exp_sender\E/); my $new_filename3 = $filename1; $new_filename3 =~ s/(\.gpg)|(\.encrypted)/\.decrypted/; print ".PGP ERROR, why the second time but not the first?:'$signer' is + not '$exp_sender'.\n" unless ($signer =~ m/\Q$exp_sender\E/); 1;

    And below is the out put I get from the above script

    $ perl match_test.pl .GPG FILE ERROR:'Some person <someone@this.com>' is not ''. .PGP ERROR, why the second time but not the first?:'Some person <someo +ne@this.com>' is not ''.

    the_Don
    ...making offers others can't rufuse.

      Strangely enough, you've hit a regular expression gotcha.

      The empty regular expression has a special meaning: try again the last regular expression that successfully matched. What is perhaps less obvious is that perl checks for an empty expression after interpolating variables, such as the \Q$exp_sender\E in your example.

      Here's a snippet to illustrate:

      "test" =~ /t/; # successful match my $var = ""; print "matched 't'\n" if "t" =~ /\Q$var\E/; print "matched 'u'\n" if "u" =~ /\Q$var\E/;

      A couple of alternative approaches, depending on what you're trying to achieve:

      print "'$signer' is not '$exp_sender'\n" unless $signer eq $exp_sender; print "'$signer' is not '$exp_sender'\n" unless index($signer, $exp_sender) >= 0; print "'$signer' is not '$exp_sender'\n" unless $exp_sender eq '' || $signer eq $exp_sender;

      Hugo

        First of all - Thank you very much.

        I am wondering if there is a way to clear out the $& value that holds the value of the last successful match (which is what I think is being used, if its one of the other perl vars, please correct me).

        If there is not a way around it, I will have to change more of the original code, but I was hoping that I could clear and or reset the perl var.

        PS. I am aware that $& is described as READONLY, but there seems to be tricks for everything, I am hoping there is a trick for this as well. i.e. a match that will effectively clear the value?

        the_Don
        ...making offers others can't rufuse.