Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Exec'ing a regex stored in a scalar variable

by brycen (Monk)
on Mar 11, 2005 at 21:37 UTC ( [id://438820]=perlquestion: print w/replies, xml ) Need Help??

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

Assuming my regular expression comes to me from some outside source, is this the most elegant way to apply it to a string?:
    # this came from somewhere else
    $regex    = "s/a/b/g";

    # now apply it to my string
    $string = "apple\n";
    eval("\$string =~ $regex");
    print $string;
I half expected this to work:
    $string =~ $regex;
But in fact it seems to do nothing.
  • Comment on Exec'ing a regex stored in a scalar variable

Replies are listed 'Best First'.
Re: Exec'ing a regex stored in a scalar variable
by saintmike (Vicar) on Mar 11, 2005 at 21:55 UTC
    You need to distinguish between the search pattern and the replace string. To store the compiled search regex, use

    $search = qr/pattern/;
    and to use it in a substitution command, just plug it in:

    s/$search/replace/g;
    To store the entire substitution, I'd go with a subref:

    my $rep = sub { $_[0] =~ s/a/b/g }; my $string = "abc"; $rep->($string); print "$string\n";
Re: Exec'ing a regex stored in a scalar variable
by ikegami (Patriarch) on Mar 11, 2005 at 22:34 UTC

    $string =~ $regexp works if $regexp contains a regular expression. It doesn't in your case. "s/.../.../" is the Perl substitution operator, not a regular expression.

    If given strings, the best way I can think of doing a substitution is:

    $regexp = "a"; $subst = "b"; $global = 1; if ($global) { $string =~ s/$regexp/$subst/g; } else { $string =~ s/$regexp/$subst/; } # (?i...) can be used in $regexp for /.../i # (?m...) can be used in $regexp for /.../m # (?s...) can be used in $regexp for /.../s # (?x...) can be used in $regexp for /.../x # /g cannot be stored in $regexp, thus the need for $global. # /e cannot be stored in $regexp.

      Depends on your amitiousness.

      $regexp = qr/a(b+)c/; $subst = 'c$1a'; my @a = $string =~ $regexp; $subst =~ s/\$(\d)/$a[$1-1]/ge; $string =~ s/$regexp/$subst/;
      Warning - untested. I know I've used code similar to this in the past with a limited amount of success. (i.e., it worked for me for what I needed it to work for, and this is not a cut&paste job of that code.)

Re: Exec'ing a regex stored in a scalar variable
by jdalbec (Deacon) on Mar 12, 2005 at 01:21 UTC
    Applying eval to a string is a great way to expose yourself to code injection attacks. Maybe you need to tell us more about the "somewhere else" your regex comes from. What types of regexes are you expecting?
      There's no injection problem here. This is just a small utility to convert an Excel spreadsheet into an SQL database. There is a hash to define the mapping, and another to apply any hacks needed to the data:
      my %column_match = (
          'SP_CITYNAME'           => 'pod_city',
          'SP_STATE'              => 'pod_state',
          'SP_POSTALCODE'         => 'pod_zip',
          'SP_LANDMARKNAME'       => 'pod_short_name',
      );
      my %column_regex = (
          'SP_CITYNAME'       => 's/\s*$//g',
          'SP_LANDMARKNAME'   => 's/^Landmark - //',
      );
      
      Though I now realize this is hardly flexible enough. What if someone wanted to hack the data with "join(' ',map{ucfirst(lc($_))}split(/\s/,$_[0]));"?
Re: Exec'ing a regex stored in a scalar variable
by sh1tn (Priest) on Mar 11, 2005 at 23:11 UTC
    my @regexs; !/^\s*$/ and push @regexs, $_ while <DATA>; my @smth = ("test_for r1", "+ test_for_r2 +"); $_ = eval for @regexs; for my $string (@smth){ for(@regexs){ $string =~ /$_/ and print "pattern \"$_\" is ok for \"$string\"$/" } } # STDOUT: # pattern "(?i-xsm:^\w+\s+\w+$)" is ok for "test_for r1" # pattern "(?i-xsm:^\W+\w+\W+$)" is ok for "+ test_for_r2 +" __DATA__ qr{^\w+\s+\w+$}i qr{^\W+\w+\W+$}i


Log In?
Username:
Password:

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

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

    No recent polls found