Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Using variables in regex search

by lancer (Beadle)
on Aug 14, 2011 at 13:07 UTC ( #920222=perlquestion: print w/replies, xml ) Need Help??
lancer has asked for the wisdom of the Perl Monks concerning the following question:

Hi All!

I'm trying to find a string in a text, and the string is coming from a variable.

What expression should I use?

Will this code work?

$text =~ m/$str/;
Will I need to escape the contents of "$str" ?

Thank you

Replies are listed 'Best First'.
Re: Using variables in regex search
by Tanktalus (Canon) on Aug 14, 2011 at 13:15 UTC
    If you're looking for a literal string, use index instead of a regex. If the string is a regex itself, then what you have is fine.
      Thanks, Tanktalus!

      I'm looking for a literal string. But I would like to find all occurrences of it, not just the first one (index gives only the first match).

      A regex search could iterate over all matches. But I think I have to escape the contents of $str, because it's not a regex expression itself...

        Now it's sounding like an XY Problem. What do you need to do with all found occurrences? Modify them? With a literal string, I can only think of three things to do with it: check if it's there (boolean - a single match is sufficient), modify it (s/../../), or count it. And the vast majority IME is the first one. Only the modification one "needs" a regex, and even that isn't really true.

        That all said, index can find multiple matches as well:

        $ perl -lE ' my ($haystack,$needle)=@ARGV; my $i=0; my @found; while(-1 != (my $curidx = index $haystack, $needle, $i)) { push @found, $curidx; $i = $curidx+1 }; say "found at $_" for @found ' abcsdfabcasegabc abc found at 0 found at 6 found at 13
        If you're doing a modification, just use rindex - it's even easier, use rindex (though this will be a bit slower for longer strings with many matches).
        $ perl -lE ' my ($haystack,$needle,$new)=@ARGV; while(-1 != (my $curidx = rindex $haystack, $needle)) { substr $haystack, $curidx, length($needle), $new }; say "new string: $haystack" ' abcsdfabcasegabc abc foo new string: foosdffooasegfoo
        The only challenge with this method is if $new contains $needle in it - then it won't work.

        If you are going with the substitution and want to use a regex (probably safer once you escape it), use "\Q" before your string:

        s/\Q$str\E/$new/g; # since \E is at the end, it's not really required.
        Hope that helps.

Re: Using variables in regex search
by toolic (Bishop) on Aug 14, 2011 at 16:58 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://920222]
Approved by Perlbotics
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (12)
As of 2017-09-22 12:18 GMT
Find Nodes?
    Voting Booth?
    During the recent solar eclipse, I:

    Results (262 votes). Check out past polls.