Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Switch/Format to not interpret metacharacters in regex?

by mis (Initiate)
on Dec 04, 2019 at 01:15 UTC ( [id://11109637]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Perlmonks,

Is if possible to have a string interpreted as a literal without pre-escapting in a regex. Consider:

#!/opt/local/bin/perl my $a = "Tick F***ing Tock"; my $b = "Friday night at 11:30pm the start of a new series, 'Tick F*** +ing Tock' explores..."; if ($b =~ /$a/) { print "..do something..\n"; }
This will return:
$ ./t.pl Nested quantifiers in regex; marked by <-- HERE in m/Tick F** <-- HERE + *ing Tock/ at ./t.pl line 5.
Of course this will work:
#!/opt/local/bin/perl my $a = "Tick F***ing Tock"; my $b = "Friday night at 11:30pm the start of a new series, 'Tick F*** +ing Tock' explores..."; $a =~ s/([\(\)\[\]\{\}\\\*\?\.\$\^\@\!\&])/\\$1/g; if ($b =~ /$a/) { print "..do something..\n"; }
Result:
$ ./t.pl ..do something..
However there will result in a long list of escapes to make parsing safe as '$a' in my script is dynamic and not fixed like in this example... Also there will no doubt be a significant performance hit considering the number of times I'd be looping over the regex...

Thanks in advance.

Replies are listed 'Best First'.
Re: Switch/Format to not interpret metacharacters in regex?
by tybalt89 (Monsignor) on Dec 04, 2019 at 01:36 UTC
      Thank you! (knew it was there somewhere but couldn't spot it reading perlre.. hangover doesn't help. :D )
Re: Switch/Format to not interpret metacharacters in regex?
by GrandFather (Saint) on Dec 04, 2019 at 01:47 UTC

    If what you really want to do is just look for one string in another than index is the better tool:

    use strict; use warnings; my $match = "Tick F***ing Tock"; my $str = "Friday night at 11:30pm the start of a new series, 'Tick F* +**ing Tock' explores..."; if (-1 != index $str, $match) { print "..do something..\n"; }

    If you really want to use a regex then use quotemeta to do the quoting for you:

    use strict; use warnings; my $match = "Tick F***ing Tock"; my $str = "Friday night at 11:30pm the start of a new series, 'Tick F* +**ing Tock' explores..."; $match = quotemeta $match; if ($str =~ $match) { print "..do something..\n"; }
    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
      I'm actually fixing someone elses code, based on the actual code the fix might be as simple as:
      if (lc($b) eq lc($a)) { print "do something...\n"; }
      However the first answer (using /\Q$a\E/) has immediately fixed the issue and knowing the data it will be a permanent fix for the issue... it also taught me something that I probably have come across in the past... 20+years working with perl and I still learn something new every so often... :)

      Thanks, all.

        G'day mis,

        Welcome to the Monastery.

        Two quick points:

        • $a and $b are special variables which I'd recommend avoiding except for their special purposes. See perlvar: $a for more information.
        • Instead of using lc (or uc) consider fc. Note that you'll need Perl 5.16 for that.

        — Ken

Re: Switch/Format to not interpret metacharacters in regex?
by Laurent_R (Canon) on Dec 05, 2019 at 17:27 UTC
    See also the built-in quotemeta function (which does something very similar to \Q ... \E).
      See also the built-in quotemeta function (which does something very similar to \Q ... \E).

      Not only similar. quotemeta is the function implementing the \Q escape, according to quotemeta.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
        Yes, afoken++, you're right. I did not want to say that they are identical, because they have a different calling syntax, but, yes, they do the same thing.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11109637]
Approved by GrandFather
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2024-04-26 04:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found