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

Consider this function:
sub foo { my ($text, $to) = @_; $text =~ s{(\d+)}{$to}; $text; } print foo("123", 'capture 1 is $1');
I'd like it to print 'capture 1 is 123', but it prints 'capture 1 is $1'. It's treating $to as a string literal and ignoring the occurrence of $1 in the string.

I have since figured out this:

sub bar { my ($text, $to) = @_; $text =~ s{(\d+)}{qq{qq{$to}}}ee; $text; } print bar("456", 'capture 1 is $1'); # prints capture 1 is 456

Is there any other way to get $1, $2, etc. interpolated without resorting to using the /ee modifier?

Replies are listed 'Best First'.
Re: Interpolate $1 in: s{...}{$to}
by ikegami (Patriarch) on Jun 24, 2010 at 22:06 UTC
    'capture 1 is $1' is a template. You need something to process that template. If you want to keep the current template format, you could use /ee aka eval EXPR (which has safety issues) or String::Interpolate (which has an unconventional interface), or you could switch to something designed to be a template (e.g. Template::Toolkit).
Re: Interpolate $1 in: s{...}{$to}
by MidLifeXis (Monsignor) on Jun 25, 2010 at 13:02 UTC

    or use sprintf. Search for "format parameter index" if you need to rearrange or repeat the ordering of the matches in the output.

    sub foo { my ($from, $to) = @_; return sprintf($to, ($from =~ /.../)); }

    --MidLifeXis