Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

RE: RE: Selective substitution: not in Perl?

by nuance (Hermit)
on Aug 16, 2000 at 14:39 UTC ( [id://28090]=note: print w/replies, xml ) Need Help??


in reply to RE: Selective substitution: not in Perl?
in thread Selective substitution: not in Perl?

That doesn't work, suppose I have the string "abacab" and want to replace the second a with an upper case A. Your regex doesn't match. How about this (untested):
#!/usr/bin/perl -w use strict; my $string = "abacab"; print "$string\n"; my $pattern = "a"; my $better = "A"; my $n=1; my $i=0; $string =~ s/($pattern)/$i == $n ? $better : $1; i++/ge; print "$string\n"

Nuance

Replies are listed 'Best First'.
RE: RE: RE: Selective substitution: not in Perl?
by atl (Pilgrim) on Aug 16, 2000 at 15:27 UTC
    Black magic! I'm really impressed, I didn' know you can put that all into the substitution pattern. /me bows to Nuance ...

    As for my solution, I was focused on the sample input given, I didn't think of the more general problem. But you're right about this.

    As for your script, it works with a small alteration:

    $string =~ s/($pattern)/$i++ == $n ? $better : $1/ge;
    If you increment $i in a seperate statement, the whole block evaluates to the value of $i und you get
    abacab 0b1c2b
    Ok, now we're having fun :-)...

    Andreas (waiting for the chinese food delivery service ...)

      To make it even clearer, remember that the right side of the s///ge can be an arbitrary block. Here's the "Perl Bowling" style written for clarity:
      { my $count = 0; $string =~ s{($pattern)}{ my $source = $1; $count++; if ($count == $target) { $source = $replacement; # replace! } $source; # either original or replacement now }ge; };
      And yes, you can actually write it like that, just as you see. If you're doing anything odd in the right hand side in a s///e, I recommend expanding it out like that.

      -- Randal L. Schwartz, Perl hacker

RE: RE: RE: Selective substitution: not in Perl?
by Anonymous Monk on Aug 17, 2000 at 01:46 UTC
    Thanks, your solution works great! I wrote a sub to convert sed-ish s///n constructs to your format, making conversion from sed easier:
    sub seval { my ($sub) = shift; $vni++; $sub =~ s#s/([^/]+)/([^/]+)/(.+)#s/\1/\$i$vni++ == \3 ? \2 : \$&/e +gs#; return $sub; } # Evals 's/foo/$i1++ == 1 ? bar : $&/egs' eval(seval("s/foo/bar/2"));
    Thanks again.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://28090]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (5)
As of 2024-03-29 11:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found