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

how do i use a regex that is in a string

my script looks in a file and may return a line that contains a regular expression.

something like s/a/b/g
So i know have a $ which contains the above regex.

Is it possible to use that string as a regular expression on another string.

eg

$a = "aaabbbaaa";
$b = "s/b/c/g";

$a =~$b;

That obviously doesnt work but you see what i'm trying to do.

Thanks

Mark

Replies are listed 'Best First'.
Re: using a regex which is in a string
by ikegami (Patriarch) on Apr 20, 2005 at 16:18 UTC

    s/b/c/g is not a regexp, it's a Perl expression. Only the b of s/b/c/g is a regexp.

    eval is provided to execute Perl expressions:

    $a = "aaabbbaaa"; $b = "s/b/c/g"; eval '$a =~ ' . $b;

    or

    local $_ = "aaabbbaaa"; $b = "s/b/c/g"; eval $b;

    Unfortunately, eval EXPR can be used to execute any Perl expressions, even calls to system, for example. It would be safer if you were provided the regexp and the substitution parts seperately, as I mentioned in this node:

    # Inputs # ====== $string = "aaabbbaaa"; $regexp = "b"; $subst = "c"; $global = 1; # (?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, but I'm not supporting it. # Guts # ==== # Check user input. eval { # Let's explicitely be on the safe side. no re 'eval'; $regexp = qr/$regexp/; }; # Handle bad user input. die("Bad regexp supplied: $@\n") if $@; # Do the work. if ($global) { $string =~ s/$regexp/$subst/g; } else { $string =~ s/$regexp/$subst/; }

    Known bugs: People mentioned that this does not provide a means of using $1, $2, etc in $subst.

Re: using a regex which is in a string
by davido (Cardinal) on Apr 20, 2005 at 16:19 UTC

    Something like this:

    my $c = 'aaabbbaaa'; my $d = 's/b/c/g'; eval "\$c =~ $d"; die "Failure: $@\n" if $@; print $c, "\n";

    Depending on where your $d is coming from, this could expose you to code injection. Be cautious.

    Also notice I refrained from using $a and $b. This is usually a good idea, as the use of $a and $b can get confusing since sort uses special global versions of $a and $b also.


    Dave

Re: using a regex which is in a string
by japhy (Canon) on Apr 20, 2005 at 18:13 UTC