in reply to Regex Substitution, Interpolating on the RHS?

Another approach to delayed evaluation is to use closures (update: ok, not really closures, but subroutines). To get a sub to be evaluated in the double-quotish context of a s/// replacement, it needs to be part of a block. The only block interpolated in double quotes is a deref.

So you make the closure return a ref to the string you want, and deref it in the replacement. It will be evaluated at replacement time, and you get the substitution you're looking for.

my $regex = ['(foo)',sub {\"bar$1"}]; my $string = 'blah foo blah'; $string =~ s/$regex->[0]/${$regex->[1]->()}/; print "S=$string\n";

Caution: Contents may have been coded under pressure.

Replies are listed 'Best First'.
Re^2: Regex Substitution, Interpolating on the RHS?
by Cody Pendant (Prior) on Jul 18, 2005 at 23:30 UTC
    That's very smart and I'm very grateful. Can I spoil all that for asking how I get a generalised solution where I can have the same code run both evaluated and non-evaluated regexes?

    How do I code, for instance, so that $regex may sometimes be:

    my $regex = ['(foo)',sub {\"bar$1"}];
    but at other times just
    my $regex = ['foo','bar'];

    I'm guessing I'll need to use ref() or something?



    ($_='kkvvttuu bbooppuuiiffss qqffssmm iibbddllffss')
    =~y~b-v~a-z~s; print
      Yes, you would check ref($regex->[1]). It will be 'CODE' for a coderef and false (empty) for a non-ref. You could put the whole test/selection into the block like so:
      my $regex = ['(foo)',sub {\"bar$1"}]; my $string = 'blah foo blah'; $string =~ s/$regex->[0]/${(ref($regex->[1]) eq 'CODE' ? $regex->[1]-> +() : \$regex->[1])}/; print "S=$string\n";

      Caution: Contents may have been coded under pressure.