Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

manipulating capture groups in s///

by glwtta (Hermit)
on Nov 11, 2003 at 19:10 UTC ( [id://306323]=perlquestion: print w/replies, xml ) Need Help??

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

I am sure this has been asked before, but I couldn't find the answer on my own.

Very simply, I want to do a substitution where the string being substituted in, is based on what was matched; in other (clearer) words, it would look like: s/(bar)/&foo($1)/g;.

The best I've been able to come up with is: s/((bar)(?{$b=foo($2)}))/$b/g;

I am a little wary of this, as I am not entirely certain that I understand exactly how it's doing what it's doing (additionaly the docs seem to suggest that (?{}) is liable to open the gates of hell and unleash all sorts of despair on humanity). Additionally, as I understand it, this requires a global variable (the use of $b is quite intentional here).

So my question is: (a) am I going to run into trouble with the above? and (b) is there a better way?

Replies are listed 'Best First'.
Re: manipulating capture groups in s///
by diotalevi (Canon) on Nov 11, 2003 at 19:19 UTC

    Yes, you'll run into trouble, you should have used the /e flag. It causes the right side of your expression to be executed and its return value is used as the replacement.

    s((bar))(foo($1))ge
      Neat way to parenthesize. I need to remember this for obfuscations. :)

      Makeshifts last the longest.

Re: manipulating capture groups in s///
by Anonymous Monk on Nov 11, 2003 at 19:26 UTC

    If the replacement rules can be formulated in a look up table just use a hash:

    my %lookup = ( bar => 'thing1', foo => 'thing2'); $_ = "this has bar and foo\n"; s/(bar|foo)/$lookup{$1}/g; print; #=> this has thing1 and thing2

    If the replacement requires computation, then use the /e modifier which evaluates the replacement side of the s/// operator as Perl code:

    sub foo { return reverse uc shift } $_ = "this has bar and foo\n"; s/(bar|foo)/foo($1)/eg; print; #=> this has RAB and OOF
Re: manipulating capture groups in s///
by ptkdb (Monk) on Nov 11, 2003 at 20:17 UTC
    if you're so concerned about using (?{}), why not simply do your substitution in two steps?

    my($b) = /(bar)/ ; # step 1 find the string my($substitute) = foo($b) ; # Step 2 make the substitution s/bar/$substitute/ ; # plug it in

Log In?
Username:
Password:

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

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

    No recent polls found