here comes another way :)
#!/usr/local/bin/perl -w
use strict;
my $s = "Terence and Philip are sweet\n";
my $c = 'e';
my $r = 1;
my $n = 3;
sub mine
{
my ($str,$chr,$new,$nbr)=@_;
my $reg="(.+?)$chr" x --$nbr;
$_=$str;
(/$reg/)&&($str=$&)&&($_=$')&&(s/$chr/$new/g);
return $str.$_;
}
print mine($s,$c,$r,$n);
The code for benchmarking agains BBFU's proc and Quent's
#!/usr/local/bin/perl -w
use strict;
my $s = "Terence and Philip are sweet\n";
my $c = 'e';
my $r = 1;
my $n = 3;
sub mine
{
my ($str,$chr,$new,$nbr)=@_;
my $reg="(.+?)$chr" x $nbr;
$_=$str;
(/$reg/)&&($str=$&)&&($_=$')&&(s/$chr/$new/g);
return $str.$_;
}
sub bbfus {
my ($str, $chr, $rep, $nth) = @_;
my $pos = 0;
$pos = index($str, $chr, $pos+1) for(1..$nth);
substr($str, $pos) =~ s/$chr/$rep/g;
return $str;
}
sub quents {
my ($str, $chr, $rep, $nth) = @_;
my $i = 1;
$str =~ s/($chr)/$i++<$nth?$1:$rep/eg;
return $str;
}
use Benchmark qw( timethese cmpthese );
cmpthese(500000, {
"BBFU'S" => sub { bbfus ($s, $c, $r, $n) },
"Quent's" => sub { quents ($s, $c, $r, $n) },
"MINE" => sub { mine ($s,$c,$r,$n) },
});
AND THE BENCHMARKS :)
Benchmark: timing 500000 iterations of BBFU'S, MINE, Quent's...
BBFU'S: 20 wallclock secs (19.45 usr + 0.00 sys = 19.45 CPU) @ 25
+706.94/s (n=500000)
MINE: 19 wallclock secs (19.87 usr + 0.02 sys = 19.88 CPU) @ 25
+146.69/s (n=500000)
Quent's: 25 wallclock secs (24.97 usr + 0.00 sys = 24.97 CPU) @ 20
+026.70/s (n=500000)
Rate Quent's MINE BBFU'S
Quent's 20027/s -- -20% -22%
MINE 25147/s 26% -- -2%
BBFU'S 25707/s 28% 2% --