The answers above are good. However, the substr function will let you replace characters in place, saving one of the calls to substr. Here's a one-liner that does what you want perl -e "$_='aaaaaaaaaa'; substr($_,0,-4)='X' x (length($_) -4); print
+"
Or you could use the four argument version of substr: perl -e "$_='1234567890'; substr($_,0,-4, 'X' x (length($_) - 4)); pri
+nt"
Update: I added these two methods to maverick's benchmark, with the following results:
use Benchmark;
my $string = "1234567890";
timethese(-5, {
'Regexp' => sub { $string =~ s/(.*?)(....)$/("X" x length($1)).
+$2/e; },
'Regexp D&P' => sub { $string =~ s/.(?!.{0,3}$)/x/g; },
'Substring' => sub { $string = length substr($string,0,-4). substr
+($string,- 4) },
'mysubstr' => sub { substr($string,0,-4)='X' x (length($string) - 4)
+ },
'fourarg' => sub { substr($string, 0, -4, 'X' x (length($string
+) - 4)) }
});
Benchmark: running Regexp, Regexp D&P, Substring, fourarg, mysubstr, e
+ach for at
least 5 CPU seconds...
Regexp: 6 wallclock secs ( 5.35 usr + 0.00 sys = 5.35 CPU) @ 40
+933.99/s (n=218915)
Regexp D&P: 5 wallclock secs ( 5.18 usr + 0.00 sys = 5.18 CPU) @ 90
+739.67/s (n=469850)
Substring: 6 wallclock secs ( 5.19 usr + 0.00 sys = 5.19 CPU) @ 31
+6184.66/s (n=1640366)
fourarg: 6 wallclock secs ( 5.10 usr + 0.00 sys = 5.10 CPU) @ 37
+0755.39/s (n=1890111)
mysubstr: 6 wallclock secs ( 5.39 usr + 0.00 sys = 5.39 CPU) @ 27
+1099.83/s (n=1460957)
Surprisingly (to me at least), mysubstr (the first method I proposed) is slower than the original substr method.
Update2: fixed silly error (double assignment) in mysubstr and added
'X' x to the original Substr to make things even, reran benchmarks.
|