Using variable in replacement expression

Discussion in 'Perl Misc' started by RobV, Aug 8, 2012.

  1. RobV

    RobV Guest

    I'm trying to do a global replace with a varying replacement string which includes a counter to count the replacements.
    The idea is this (replacing all "xy" strings):
    Source: "ab xy cd xy ef xy gh"
    Result: "ab Mark1 cd Mark2 ef Mark3 gh"

    I read through perlre and the best I can come up with is below. Yet it doesn't do what I wanted, the replacement is identical every time:

    $cnt = 1;
    $replace = '"Mark$cnt"';
    $s = "ab xy cd xy ef xy gh";

    while ($s =~ s/xy/$replace/gee) {
    $cnt++;
    }
    print $s;

    Result is: "ab Mark1 cd Mark1 ef Mark1 gh"

    My understanding of the /ee modifier is that it forces the right-hand side to be evaluated every time, but somewhere in my understanding something seems to be missing.

    I'd be grateful if someone could point me the way.
    Thanks in advance,

    Rob V.
     
    RobV, Aug 8, 2012
    #1
    1. Advertising

  2. RobV

    Tim McDaniel Guest

    In article <>,
    RobV <> wrote:
    >I'm trying to do a global replace with a varying replacement string
    >which includes a counter to count the replacements.
    >The idea is this (replacing all "xy" strings):
    > Source: "ab xy cd xy ef xy gh"
    > Result: "ab Mark1 cd Mark2 ef Mark3 gh"
    >
    >I read through perlre and the best I can come up with is below. Yet
    >it doesn't do what I wanted, the replacement is identical every time:
    >
    >$cnt = 1;
    >$replace = '"Mark$cnt"';
    >$s = "ab xy cd xy ef xy gh";
    >
    >while ($s =~ s/xy/$replace/gee) {
    > $cnt++;
    >}
    >print $s;


    As a side note: even in a simple test program, it's best to keep the
    discipline of
    use warnings;
    use strict;
    and "my"ing all variables.

    >Result is: "ab Mark1 cd Mark1 ef Mark1 gh"
    >
    >My understanding of the /ee modifier is that it forces the right-hand
    >side to be evaluated every time, but somewhere in my understanding
    >something seems to be missing.


    Print $cnt after the loop. You'll see that it's 2. That means that
    the loop iterated only once.

    The problem is the "g" modifier. It replaces ALL occurrences the
    first time it runs.

    "g" in general is a good idea, to prevent an infinite loop if the RHS
    happened to contain the LHS (that is, if $replace contained "xy").

    This works for me in 5.14.2:

    my $s = "ab xy cd xy ef xy gh\n";
    my $cnt = 0;
    $s =~ s/xy/++$cnt, "Mark$cnt"/ge;
    print $s;

    and therefore

    my $s = "ab xy cd xy ef xy gh\n";
    my $cnt = 0;
    my $replace = '++$cnt, "Mark$cnt"';
    $s =~ s/xy/$replace/gee;
    print $s;

    --
    Tim McDaniel,
     
    Tim McDaniel, Aug 8, 2012
    #2
    1. Advertising

  3. RobV

    Guest

    On Wednesday, August 8, 2012 11:25:27 PM UTC+2, RobV wrote:
    > I'm trying to do a global replace with a varying replacement string which includes a counter to count the replacements.
    >
    > The idea is this (replacing all "xy" strings):
    >
    > Source: "ab xy cd xy ef xy gh"
    >
    > Result: "ab Mark1 cd Mark2 ef Mark3 gh"
    >
    >
    >
    > I read through perlre and the best I can come up with is below. Yet it doesn't do what I wanted, the replacement is identical every time:
    >
    >
    >
    > $cnt = 1;
    >
    > $replace = '"Mark$cnt"';
    >
    > $s = "ab xy cd xy ef xy gh";
    >
    >
    >
    > while ($s =~ s/xy/$replace/gee) {
    >
    > $cnt++;
    >
    > }
    >
    > print $s;
    >
    >
    >
    > Result is: "ab Mark1 cd Mark1 ef Mark1 gh"
    >
    >
    >
    > My understanding of the /ee modifier is that it forces the right-hand side to be evaluated every time, but somewhere in my understanding something seems to be missing.
    >
    >
    >
    > I'd be grateful if someone could point me the way.
    >
    > Thanks in advance,
    >
    >
    >
    > Rob V.




    On Wednesday, August 8, 2012 11:25:27 PM UTC+2, RobV wrote:
    > I'm trying to do a global replace with a varying replacement string which includes a counter to count the replacements.
    >
    > The idea is this (replacing all "xy" strings):
    >
    > Source: "ab xy cd xy ef xy gh"
    >
    > Result: "ab Mark1 cd Mark2 ef Mark3 gh"
    >
    >
    >
    > I read through perlre and the best I can come up with is below. Yet it doesn't do what I wanted, the replacement is identical every time:
    >
    >
    >
    > $cnt = 1;
    >
    > $replace = '"Mark$cnt"';
    >
    > $s = "ab xy cd xy ef xy gh";
    >
    >
    >
    > while ($s =~ s/xy/$replace/gee) {
    >
    > $cnt++;
    >
    > }
    >
    > print $s;
    >
    >
    >
    > Result is: "ab Mark1 cd Mark1 ef Mark1 gh"
    >
    >
    >
    > My understanding of the /ee modifier is that it forces the right-hand side to be evaluated every time, but somewhere in my understanding something seems to be missing.
    >
    >
    >
    > I'd be grateful if someone could point me the way.
    >
    > Thanks in advance,
    >
    >
    >
    > Rob V.




    On Wednesday, August 8, 2012 11:25:27 PM UTC+2, RobV wrote:
    > I'm trying to do a global replace with a varying replacement string which includes a counter to count the replacements.
    >
    > The idea is this (replacing all "xy" strings):
    >
    > Source: "ab xy cd xy ef xy gh"
    >
    > Result: "ab Mark1 cd Mark2 ef Mark3 gh"
    >
    >
    >
    > I read through perlre and the best I can come up with is below. Yet it doesn't do what I wanted, the replacement is identical every time:
    >
    >
    >
    > $cnt = 1;
    >
    > $replace = '"Mark$cnt"';
    >
    > $s = "ab xy cd xy ef xy gh";
    >
    >
    >
    > while ($s =~ s/xy/$replace/gee) {
    >
    > $cnt++;
    >
    > }
    >
    > print $s;
    >
    >
    >
    > Result is: "ab Mark1 cd Mark1 ef Mark1 gh"
    >
    >
    >
    > My understanding of the /ee modifier is that it forces the right-hand side to be evaluated every time, but somewhere in my understanding something seems to be missing.
    >
    >
    >
    > I'd be grateful if someone could point me the way.
    >
    > Thanks in advance,
    >
    >
    >
    > Rob V.




    On Wednesday, August 8, 2012 11:25:27 PM UTC+2, RobV wrote:
    > I'm trying to do a global replace with a varying replacement string which includes a counter to count the replacements.
    >
    > The idea is this (replacing all "xy" strings):
    >
    > Source: "ab xy cd xy ef xy gh"
    >
    > Result: "ab Mark1 cd Mark2 ef Mark3 gh"
    >
    >
    >
    > I read through perlre and the best I can come up with is below. Yet it doesn't do what I wanted, the replacement is identical every time:
    >
    >
    >
    > $cnt = 1;
    >
    > $replace = '"Mark$cnt"';
    >
    > $s = "ab xy cd xy ef xy gh";
    >
    >
    >
    > while ($s =~ s/xy/$replace/gee) {
    >
    > $cnt++;
    >
    > }
    >
    > print $s;
    >
    >
    >
    > Result is: "ab Mark1 cd Mark1 ef Mark1 gh"
    >
    >
    >
    > My understanding of the /ee modifier is that it forces the right-hand side to be evaluated every time, but somewhere in my understanding something seems to be missing.
    >
    >
    >
    > I'd be grateful if someone could point me the way.
    >
    > Thanks in advance,
    >
    >
    >
    > Rob V.
     
    , Aug 8, 2012
    #3
  4. RobV

    Guest

    On Thursday, August 9, 2012 12:42:15 AM UTC+2, Tim McDaniel wrote:
    > In article <>,
    >
    > RobV <> wrote:
    >
    > >I'm trying to do a global replace with a varying replacement string

    >
    > >which includes a counter to count the replacements.

    >
    > >The idea is this (replacing all "xy" strings):

    >
    > > Source: "ab xy cd xy ef xy gh"

    >
    > > Result: "ab Mark1 cd Mark2 ef Mark3 gh"

    >
    > >

    >
    > >I read through perlre and the best I can come up with is below. Yet

    >
    > >it doesn't do what I wanted, the replacement is identical every time:

    >
    > >

    >
    > >$cnt = 1;

    >
    > >$replace = '"Mark$cnt"';

    >
    > >$s = "ab xy cd xy ef xy gh";

    >
    > >

    >
    > >while ($s =~ s/xy/$replace/gee) {

    >
    > > $cnt++;

    >
    > >}

    >
    > >print $s;

    >
    >
    >
    > As a side note: even in a simple test program, it's best to keep the
    >
    > discipline of
    >
    > use warnings;
    >
    > use strict;
    >
    > and "my"ing all variables.
    >
    >
    >
    > >Result is: "ab Mark1 cd Mark1 ef Mark1 gh"

    >
    > >

    >
    > >My understanding of the /ee modifier is that it forces the right-hand

    >
    > >side to be evaluated every time, but somewhere in my understanding

    >
    > >something seems to be missing.

    >
    >
    >
    > Print $cnt after the loop. You'll see that it's 2. That means that
    >
    > the loop iterated only once.
    >
    >
    >
    > The problem is the "g" modifier. It replaces ALL occurrences the
    >
    > first time it runs.
    >
    >
    >
    > "g" in general is a good idea, to prevent an infinite loop if the RHS
    >
    > happened to contain the LHS (that is, if $replace contained "xy").
    >
    >
    >
    > This works for me in 5.14.2:
    >
    >
    >
    > my $s = "ab xy cd xy ef xy gh\n";
    >
    > my $cnt = 0;
    >
    > $s =~ s/xy/++$cnt, "Mark$cnt"/ge;
    >
    > print $s;
    >
    >
    >
    > and therefore
    >
    >
    >
    > my $s = "ab xy cd xy ef xy gh\n";
    >
    > my $cnt = 0;
    >
    > my $replace = '++$cnt, "Mark$cnt"';
    >
    > $s =~ s/xy/$replace/gee;
    >
    > print $s;
    >
    >
    >
    > --
    >
    > Tim McDaniel,



    Thanks very much. It works now!

    Rob V.
     
    , Aug 8, 2012
    #4
  5. RobV

    C.DeRykus Guest

    On Wednesday, August 8, 2012 3:42:15 PM UTC-7, Tim McDaniel wrote:
    > In article <>,
    >
    > RobV <> wrote:
    >
    > >I'm trying to do a global replace with a varying replacement string

    >
    > >which includes a counter to count the replacements.

    >
    > >The idea is this (replacing all "xy" strings):

    >
    > > Source: "ab xy cd xy ef xy gh"

    >
    > > Result: "ab Mark1 cd Mark2 ef Mark3 gh"

    >
    > >

    >
    > >I read through perlre and the best I can come up with is below. Yet

    >
    > >it doesn't do what I wanted, the replacement is identical every time:

    >
    > >

    >
    > >$cnt = 1;

    >
    > >$replace = '"Mark$cnt"';

    >
    > >$s = "ab xy cd xy ef xy gh";

    >
    > >

    >
    > >while ($s =~ s/xy/$replace/gee) {

    >
    > > $cnt++;

    >
    > >}

    >
    > >print $s;

    >
    >
    >
    > As a side note: even in a simple test program, it's best to keep the
    >
    > discipline of
    >
    > use warnings;
    >
    > use strict;
    >
    > and "my"ing all variables.
    >
    >
    >
    > >Result is: "ab Mark1 cd Mark1 ef Mark1 gh"

    >
    > >

    >
    > >My understanding of the /ee modifier is that it forces the right-hand

    >
    > >side to be evaluated every time, but somewhere in my understanding

    >
    > >something seems to be missing.

    >
    >
    >
    > Print $cnt after the loop. You'll see that it's 2. That means that
    >
    > the loop iterated only once.
    >
    >
    >
    > The problem is the "g" modifier. It replaces ALL occurrences the
    >
    > first time it runs.
    >
    >
    >
    > "g" in general is a good idea, to prevent an infinite loop if the RHS
    >
    > happened to contain the LHS (that is, if $replace contained "xy").
    >
    >
    >
    > This works for me in 5.14.2:
    >
    >
    >
    > my $s = "ab xy cd xy ef xy gh\n";
    >
    > my $cnt = 0;
    >
    > $s =~ s/xy/++$cnt, "Mark$cnt"/ge;
    >
    > print $s;
    >
    >
    >
    > and therefore
    >
    >
    >
    > my $s = "ab xy cd xy ef xy gh\n";
    >
    > my $cnt = 0;
    >
    > my $replace = '++$cnt, "Mark$cnt"';
    >
    > $s =~ s/xy/$replace/gee;
    >
    > print $s;
    >
    >


    A variant sans comma operator:

    $cnt = 1;
    $replace = '"Mark" . $cnt++';
    $s =~ s/xy/$replace/gee;

    --
    Charles DeRykus
     
    C.DeRykus, Aug 11, 2012
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Daniel Bass
    Replies:
    6
    Views:
    399
    Daniel Bass
    Oct 13, 2003
  2. Henner Graubitz
    Replies:
    11
    Views:
    629
    Virgil Green
    May 25, 2004
  3. Tony
    Replies:
    2
    Views:
    129
    Tad McClellan
    Apr 21, 2005
  4. Stefan Mueller
    Replies:
    9
    Views:
    132
    Stefan Mueller
    Nov 1, 2005
  5. Replies:
    4
    Views:
    211
    Rainer Weikusat
    May 2, 2013
Loading...

Share This Page