http://www.perlmonks.org?node_id=948631

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

The following code produces this error:

Unmatched ( in regex; marked by <-- HERE in m/Hi( <-- HERE / at match_problem.pl line 14

But only if $str1 or $str2 have an upper case letter! No problem if both are lower case. Also, no problem with punctuation marks other than parentheses.

Very strange; any insight will be highly appreciated.

I'm only moderately knowledgeable; would appreciate as simply-stated an answer is possible.

Here is the code:

$str1 = "Hi("; $str2 = "hi"; if ($str2 =~ $str1) { print "Match: Yes\n"; } else { print "Match: No\n"; }

Replies are listed 'Best First'.
Re: Possible Match Problem
by ww (Archbishop) on Jan 18, 2012 at 23:03 UTC
    And, in some cases, you may want to use eq instead of relying on a regex.

    In this case, I can't reproduce your success when using all lc letters in the $strings... which is what I was trying to do as Brother toolic posted the excellent explanation that metachars, such as parens, have to be escaped (see perlre for more). But note also, below, the use of the qr in creating $str1

    #!/usr/bin/perl use strict; use warnings; # "use Diagnostics;" might help you, too. # 948631 my $str1 = qr/hi\(/; # Note use of qr here; see perldoc perlre or p +erlretut # Escaped paren; no more complaints from the r +egex engine my $str2 = "hi"; # All lc did NOT work until the paren was esca +ped if ($str2 =~ $str1) { print "Match: Yes\n"; } else { print "Match: No\n"; } say "Now, using 'eq'"; if ($str2 eq $str1) { print "Match: Yes\n"; } else { print "Match: No\n"; }
Re: Possible Match Problem
by toolic (Bishop) on Jan 18, 2012 at 22:42 UTC
    Parens are special characters in regexes and they need to be escaped: quotemeta:
    $str1 = quotemeta "Hi(";
    See also perlre.
Re: Possible Match Problem
by Marshall (Canon) on Jan 18, 2012 at 23:39 UTC
    #!/usr/bin/perl -w use strict; my $str1 = "Hi("; my $str2 = "hi"; if ($str2 =~ /\Q$str1\E/) #\Q...\E means like qr #don't interpret characters #like '(' within $str1 #use them verbatim { print "Match: Yes\n"; } else { print "Match: No\n"; } #prints Match: No $str2 = "hI("; if ($str2 =~ /\Q$str1\E/i) #/i means case insensitive { print "Match: Yes\n"; } else { print "Match: No\n"; } #prints Match: Yes
    Basically if you want to match upon string where one or more characters would mean something to a Perl regex, you need to say that: "I don't want these special characters to count, i.e. mean something in a regex sense" - otherwise when Perl interpolates that string, those characters "will count". There are a couple of ways to say "please use all these characters verbatim", I showed one of these. qr is another.
      ... a couple of ways to ... use all these characters verbatim ... qr is another.

      In no way will  qr use any metacharacters verbatim unless specifically 'told' to do so, e.g., by a  \Q ... \E escape sequence.

      >perl -wMstrict -le "my $s = 'hi('; my $rx = qr{$s}; " Unmatched ( in regex; marked by <-- HERE in m/hi( <-- HERE / at ...

      Update: See  qr in the Regexp Quote Like Operators section of perlop, also see section on 'escape sequences' (for \Q) in Quote and Quote like Operators, also in perlop.

        correct. qr is better used for other things. my example was with \Q...\E, so I'll leave it at that.
Re: Possible Match Problem
by Anonymous Monk on Jan 18, 2012 at 23:20 UTC
    I am impressed with and grateful for the speed with which I received the excellet response. I certainly learned something today. Thanks, Monks, for the help. (Oritinal poster)