Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: How do I replace a substring (if exists) with a different substring in a string?

by harangzsolt33 (Chaplain)
on Jun 25, 2016 at 18:23 UTC ( [id://1166561]=note: print w/replies, xml ) Need Help??


in reply to How do I replace a substring (if exists) with a different substring in a string?

Another way to do it is split the string at every occurrence of $find and then join it together using the new pattern $replace like this:
$string = join( $replace, split($find, $string) );
I think, this is a much neater way to do it, however I do not know how fast it is or how much more memory it uses. I have found that in JavaScript, this method works faster than the regular replace() method. Generally, working with arrays in JavaScript is always faster than working with strings. Btw could somebody do a benchmark on this to see how it compares to the other solutions?
  • Comment on Re: How do I replace a substring (if exists) with a different substring in a string?
  • Download Code

Replies are listed 'Best First'.
Re: Answer: How do I replace a substring (if exists) with a different substring in a string?
by choroba (Cardinal) on Jun 25, 2016 at 20:26 UTC
    Here's the benchmark. It seems changing the lengths of the involved strings heavily influences the results:
    #!/usr/bin/perl use warnings; use strict; use Test::More; use Benchmark qw{ cmpthese }; sub regex { my ($string, $find, $replace) = @_; $string =~ s/\Q$find/$replace/g; $string } sub substring { my ($string, $find, $replace) = @_; my $length = length $find; my $pos = 0; while (-1 != ( $pos = index $string, $find, $pos )) { substr $string, $pos, $length, $replace; } $string } sub array { my ($string, $find, $replace) = @_; join $replace, split /\Q$find/, $string, -1 } my @args = ('12a345a678a90', 'a', '||'); is regex(@args), '12||345||678||90', 'manual'; for my $args (\@args, [ '123456789abcdefghijkl' x 1000, '123456789abcdefghijkl' x 21, 'ABCDEFGH' ]) { is regex(@$args), substring(@$args), 'regex - substring'; is substring(@$args), array(@$args), 'substring - array'; cmpthese(-3, { regex => sub { regex(@$args) }, substring => sub { substring(@$args) }, array => sub { array(@$args) }, }); } done_testing(5);

    Output on my machine (Perl 5.20.1, Linux on Intel i3):

    ok 1 - manual ok 2 - regex - substring ok 3 - substring - array Rate regex substring array regex 313491/s -- -21% -36% substring 398041/s 27% -- -19% array 488419/s 56% 23% -- ok 4 - regex - substring ok 5 - substring - array Rate substring array regex substring 18505/s -- -15% -15% array 21765/s 18% -- -0% regex 21765/s 18% 0% -- 1..5

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Answer: How do I replace a substring (if exists) with a different substring in a string?
by choroba (Cardinal) on Jun 25, 2016 at 19:57 UTC
    I'd add quotemeta to $find as it can contain characters with special meanings in regular expressions.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: How do I replace a substring (if exists) with a different substring in a string?
by harangzsolt33 (Chaplain) on Jun 26, 2016 at 03:04 UTC

    I wrote a little program that runs a million string replace operations using the three methods that have been suggested here so far, and it displays how many seconds it takes to run each replace operation. (I am using tinyperl 5.8 on Windows XP Pro SP2. And I am a beginner Perl programmer.)

    As it turns out, if the length of the resulting string is longer than the original after the replacement, then it takes longer to do the replacement. Btw, the regexp has been the fastest method. The split/join method was average. And the substr method was the slowest! It was so slow that I had to abort the program after it replaced 1 million "HelloWorld" strings to "XXWorld." It took more than an hour! Anyway, here is the code:

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (6)
As of 2024-04-25 09:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found