Replace without back reference

Discussion in 'Perl Misc' started by howa, Nov 6, 2007.

  1. howa

    howa Guest

    Consider the code below:

    ############
    $str = "ABCD";

    $str =~ s/(C)D/$1F/g;

    print $str;

    ############


    It replace `ABCD` to `ABCF`, using back reference.

    I need to do these kind of operations a lot, seems using back
    reference is slow

    Any better or faster approach for the above example?

    Thanks.
    howa, Nov 6, 2007
    #1
    1. Advertising

  2. howa wrote:
    >
    > Consider the code below:
    >
    > ############
    > $str = "ABCD";
    >
    > $str =~ s/(C)D/$1F/g;
    >
    > print $str;
    >
    > ############
    >
    > It replace `ABCD` to `ABCF`, using back reference.
    >
    > I need to do these kind of operations a lot, seems using back
    > reference is slow
    >
    > Any better or faster approach for the above example?


    I don't know if this is better or faster (use Benchmark to verify):

    $str =~ s/(?<=C)D/F/g;


    John
    --
    use Perl;
    program
    fulfillment
    John W. Krahn, Nov 6, 2007
    #2
    1. Advertising

  3. On Nov 6, 11:18 am, howa <> wrote:

    > $str =~ s/(C)D/$1F/g;


    > I need to do these kind of operations a lot, seems using back
    > reference is slow
    >
    > Any better or faster approach for the above example?


    Not yet, but as of 5.10 [1] you'll be able to use \K.

    $str =~ s/C\KD/F/g;

    [1] http://www.regex-engineer.org/slides/perl510_regex.html
    Brian McCauley, Nov 6, 2007
    #3
  4. howa

    howa Guest

    On 11 6 , 9 45 , Brian McCauley <> wrote:
    > On Nov 6, 11:18 am, howa <> wrote:
    >
    > > $str =~ s/(C)D/$1F/g;
    > > I need to do these kind of operations a lot, seems using back
    > > reference is slow

    >
    > > Any better or faster approach for the above example?

    >
    > Not yet, but as of 5.10 [1] you'll be able to use \K.
    >
    > $str =~ s/C\KD/F/g;
    >
    > [1]http://www.regex-engineer.org/slides/perl510_regex.html



    Hello,

    I am using Perl 5.8.7 on Windows, when using \K, it shows:

    Unrecognized escape \K passed through at C:\test.pl line 6.

    any idea?
    howa, Nov 7, 2007
    #4
  5. On Tue, 06 Nov 2007 19:50:27 -0800, howa wrote:

    > On 11 6 , 9 45 , Brian McCauley <> wrote:
    >>
    >> Not yet, but as of 5.10 [1] you'll be able to use \K.
    >>
    >> $str =~ s/C\KD/F/g;
    >>
    >> [1]http://www.regex-engineer.org/slides/perl510_regex.html

    >
    > I am using Perl 5.8.7 on Windows, when using \K, it shows:
    >
    > Unrecognized escape \K passed through at C:\test.pl line 6.
    >
    > any idea?


    As Brian said,
    \K is not in any stable Perl at the moment.
    \K will be in Perl 5.10 when it is released.
    Tzy-Jye Daniel Lin, Nov 7, 2007
    #5
  6. howa

    Ben Morrow Guest

    Quoth Jim Gibson <>:
    >
    > I thought of another way:
    >
    > $str = s/CD/CF/g;
    >
    > It's probably about the same as look-behind, but let's throw it into
    > the benchmark program and see:
    >
    > #!/usr/local/bin/perl
    > use strict;
    > use warnings;
    > use Benchmark qw(cmpthese);
    >
    > my $str = 'ABCDEFGHCDIJCXKLCDMNOPC';
    > my $s;
    >
    > cmpthese( 1_000_000, {
    >
    > 'BckRef' => sub{ ($s = $str) =~ s/(C)D/$1F/g; },
    > 'Subst' => sub{ ($s = $str) =~ s/CD/CF/g; },
    > 'LkBnd' => sub{ ($s = $str) =~ s/(?<=C)D/F/g; },
    > 'Index' => sub{
    > $s = $str;
    > while( (my $pos = index($s,'CD') ) > -1 ) {
    > substr($s,($pos+1),1,'F');
    > }
    > }
    > });
    >
    > Rate BckRef LkBnd Index Subst
    > BckRef 263158/s -- -47% -61% -73%
    > LkBnd 500000/s 90% -- -25% -48%
    > Index 666667/s 153% 33% -- -31%
    > Subst 970874/s 269% 94% 46% --
    >
    > Surprising, no?


    No. Capturing is sloooooooow. Apart from that, I would expect the regex
    engine to be much faster than your index/substr construction, mostly
    because it uses fewer Perl ops. With such a simple pattern the regex
    will be optimised into the equivalent of index anyway, and the rx engine
    proper won't even be invoked.

    If you're really interested, you'll need to benchmark this all again
    with 5.10. A lot of work has gone into making the optimiser catch more
    'simple' cases.

    Ben
    Ben Morrow, Nov 8, 2007
    #6
    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. Brian Blais
    Replies:
    1
    Views:
    365
    Bruno Desthuilliers
    Jun 27, 2006
  2. Greg Ewing
    Replies:
    2
    Views:
    331
    Dieter Maurer
    Jun 29, 2006
  3. Alun
    Replies:
    3
    Views:
    4,479
    Masudur
    Feb 18, 2008
  4. Prasad S
    Replies:
    2
    Views:
    214
    Dr John Stockton
    Aug 27, 2004
  5. Replies:
    3
    Views:
    168
    Brian McCauley
    Sep 12, 2005
Loading...

Share This Page