http://www.perlmonks.org?node_id=1022507


in reply to Re^2: substitute characters in the RHS of a search & replace
in thread substitute characters in the RHS of a search & replace

> I guess the /r switch allows you to do it as it doesn't modify $1. Thanks, good call. I'll check it's supported on my version of perl.

If not try this instead:

my $x = q{Here are [[a variable]] number [[of words]] in brackets}; say $x; $x =~ s{\[\[(.*?)\]\]}{ (my $x=$1) =~ s/ /_/g; $x }ge; say $x;

added a /g to allow multiple chunks to be processed.

Here are [[a variable]] number [[of words]] in brackets Here are a_variable number of_words in brackets

But to improve readability I would rather opt against one-liner and call a function in the replacement part

sub blank2under { my $x=shift; $x =~ s/ /_/g; return $x; }

Cheers Rolf

update

and here a generic function to simulate /r

sub rx (&$) { my $c_regex=shift; local $_=shift; $c_regex->(); return $_ } my $x = q{Here are [[a variable]] number [[of words]] in brackets}; print "$x\n"; $x =~ s(\[\[(.*?)\]\])( rx {s/ /_/g} $1 )ge; print "$x\n";

Replies are listed 'Best First'.
Re^4: substitute characters in the RHS of a search & replace
by AnomalousMonk (Archbishop) on Mar 09, 2013 at 19:35 UTC
    ... a generic function to simulate /r ...

    Defining functions that take 'naked' subroutine blocks is, IMHO, one of the few valid reasons for using prototypes. However, there's a subtle pitfall here that belies the word 'generic' in the description of the function. The use of the  $ prototype causes behavior that will almost certainly cause puzzlement in a wider, i.e., more generic, context by imposing scalar context on its argument. Better, I think, to use  @ instead.

    >perl -wMstrict -le "sub rx (&$) { my $c_regex = shift; local $_ = shift; $c_regex->(); return $_; } ;; my $s = 'a b c'; print rx { s/ /_/g } $s; ;; my @ra = 'p q r'; print rx { s/ /_/g } @ra; " a_b_c 1 >perl -wMstrict -le "sub rx (&@) { my $c_regex = shift; local $_ = shift; $c_regex->(); return $_; } ;; my $s = 'a b c'; print rx { s/ /_/g } $s; ;; my @ra = 'p q r'; print rx { s/ /_/g } @ra; " a_b_c p_q_r
      I think a call on @something should rather generate a warning instead of trying DWIM.

      But no (good) idea how to implement that.

      Maybe better iterate over all arguments and returning a list? something called rxmap maybe?

      Cheers Rolf

        Hmmm...     This is the best I could do, but it's a bit icky for Anonymonk's OPed application:

        >perl -wMstrict -le "sub rx (&@) { return map { local $_ = $_; ()= $_[0]->(); $_; } @_[1..$#_]; } ;; my $s = 'a b c d'; print rx { s/ /_/g } $s; ;; my @ra = ('p q r', 'x y z z y'); print rx { s/ /_/g } @ra; ;; my $x = q{Here are [[a [[ variable]] number [[of ]words]] in brackets}; print qq{'$x'}; ;; $x =~ s( \[\[ (.*?) \]\] )( (rx {s/ /_/g} $1)[0] )xmsge; print qq{'$x'}; " a_b_c_d p_q_rx_y_z_z_y 'Here are [[a [[ variable]] number [[of ]words]] in brackets' 'Here are a_[[_variable number of_]words in brackets'

        Bottom line:  s///r is a lot nicer. Thanks again to whoever thought of that one.