SPUG: Metacharacters in variables in regular expressions

Christopher Howard choward at indicium.us
Mon Jan 12 13:47:00 PST 2009


I wanted to do something like this:

my $answer = <>;
chomp $answer;
if($some_earlier_var =~ /$answer/) { ### destroy the universe ### }

But I need $answer to be 'safe', so the metacharacters aren't interpreted 
as such in the regex. What is the best thing to do here, then?

I read the documentation, but was still a little uncertain. Here's a quote 
from perlre:

### START QUOTE ###
        Backslashed metacharacters in Perl are alphanumeric, such as "\b", 
"\w", "\n".  Unlike some other regular
        expression languages, there are no backslashed symbols that aren’t 
alphanumeric.  So anything that looks like
        \\, \(, \), \<, \>, \{, or \} is always interpreted as a literal 
character, not a metacharacter.  This was
        once used in a common idiom to disable or quote the special 
meanings of regular expression metacharacters in a
        string that you want to use for a pattern. Simply quote all 
non-"word" characters:

            $pattern =~ s/(\W)/\\$1/g;

        (If "use locale" is set, then this depends on the current locale.) 
Today it is more common to use the
        quotemeta() function or the "\Q" metaquoting escape sequence to 
disable all metacharacters’ special meanings
        like this:

            /$unquoted\Q$quoted\E$unquoted/

        Beware that if you put literal backslashes (those not inside 
interpolated variables) between "\Q" and "\E",
        double-quotish backslash interpolation may lead to confusing 
results.  If you need to use literal backslashes
        within "\Q...\E", consult "Gory details of parsing quoted 
constructs" in perlop.
### END QUOTE ###

So this is what I want, right?:

if($some_earlier_var =~ /\Q$answer\E/) { ### destroy the universe ### }

-- 
Christopher Howard
http://indicium.us


More information about the spug-list mailing list