Now it's sounding like an XY Problem. What do you need to do with all found occurrences? Modify them? With a literal string, I can only think of three things to do with it: check if it's there (boolean - a single match is sufficient), modify it (s/../../), or count it. And the vast majority IME is the first one. Only the modification one "needs" a regex, and even that isn't really true.
That all said, index can find multiple matches as well:
$ perl -lE '
my ($haystack,$needle)=@ARGV;
my $i=0;
my @found;
while(-1 != (my $curidx = index $haystack, $needle, $i)) {
push @found, $curidx;
$i = $curidx+1
};
say "found at $_" for @found
' abcsdfabcasegabc abc
found at 0
found at 6
found at 13
If you're doing a modification, just use rindex - it's even easier, use rindex (though this will be a bit slower for longer strings with many matches).
$ perl -lE '
my ($haystack,$needle,$new)=@ARGV;
while(-1 != (my $curidx = rindex $haystack, $needle)) {
substr $haystack, $curidx, length($needle), $new
};
say "new string: $haystack"
' abcsdfabcasegabc abc foo
new string: foosdffooasegfoo
The only challenge with this method is if $new contains $needle in it - then it won't work.
If you are going with the substitution and want to use a regex (probably safer once you escape it), use "\Q" before your string:
s/\Q$str\E/$new/g; # since \E is at the end, it's not really required.
Hope that helps. |