Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: Does s/\Q$find\E/$replace/g really a plain string replace ?

by ikegami (Patriarch)
on Oct 02, 2004 at 16:05 UTC ( [id://395898]=note: print w/replies, xml ) Need Help??


in reply to Does s/\Q$find\E/$replace/g really a plain string replace ?

Sometimes, it's just easier to try it out:

$_ = 'foo bah bar'; $find = 'bah'; $replace = '[\1]'; s/(\Q$find\E)/$replace/g; $\ = "\n"; print; # "foo [\1] bar" and not "foo [bah] bar"

But there is indeed a (more efficient?) way:

$_ = 'foo bah bar'; $find = 'bah'; $replace = '[\1]'; $idx = index($_, $find); substr($_, $idx, length($find), $replace) if $idx >= 0; $\ = "\n"; print;

Update: Here's a version that does mutliple matches:

$_ = 'foo bah bah bar'; $find = 'bah'; $replace = '[\1]'; $idx = length($_); while (($idx = rindex($_, $find, $idx-1)) >= 0) { substr($_, $idx, length($find), $replace); } $\ = "\n"; print;

Replies are listed 'Best First'.
Re^2: Does s/\Q$find\E/$replace/g really a plain string replace ?
by diotalevi (Canon) on Oct 02, 2004 at 16:23 UTC

    Good job.

    You forgot to accomodate the /g on the regexp. I'd prefer to write this as a s///g but here's your version, reconstituted for the /g feature.

    while ( ( my $index = index substr( $_, pos() ), $find), $index != -1 ) { substr $_, $index, length $find, $replace; pos() = $index + length $find; }
    while ( ( my $index = index $_, $find), $index != -1 ) { substr $_, $index, length $find, $replace; }

      At the same time you were writting that, I was writting my own /g! Mine doesn't have an infinite loop like yours does, however. Try yours with:

      $_ = 'foo bah bar'; $find = 'bah'; $replace = '[bah]'; first time in loop: foo [bah] bar second time in loop: foo [[bah]] bar third time in loop: foo [[[bah]]] bar ...
Re^2: Does s/\Q$find\E/$replace/g really a plain string replace ?
by !1 (Hermit) on Oct 02, 2004 at 21:57 UTC
    $_ = 'foo bbbbbbbah bar'; $find = 'bah'; $replace = 'ah';

    and

    $_ = 'foo babab bar'; $find = 'bab'; $replace = 'xxx';

    don't work very well.

    Perhaps something like:

    sub replace { die "Some helpful messsage" unless 3 == grep defined $_, @_[0..2]; my ($str,$find,$rep) = @_; my $i = 0; my $l = length($find); my @pos; while ($i < length($str)) { $i = index($str,$find,$i); last if $i < 0; push @pos, $i; $i += $l; } substr($str,$_,$l,$rep) for reverse @pos; return $str; }

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (4)
As of 2024-04-20 00:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found