Using eval is perfectly fine if you aren't going to be doing lots of them, but you may run into performance problems if you are.
I did this the other day: I needed to relabel the digits in a string of [1-4]+ so that it would start "1234". I was calling this routine many times, but since there were only 24 possible transformations I could cache them to avoid repeated evals:
my %tr;
sub normalise {
my $s = shift;
my $from = substr $s, 0, 4;
my $tr = $tr{$from} ||= eval qq{ sub { tr{$from}{1234} } };
&$tr for $s;
$s;
}
If you are doing this many times and the character(s) you are counting may cover too many combinations to make memoization appropriate, the best general solution is probably Roy Johnson's approach: $count = () = ($s =~ /[$search]/g)
If you specifically know that a) the $search string is always a single character, and b) that the target string is not too long then BrowserUK's xor approach: $count = ($s ^ ($search x length $s)) =~ tr/\0/\0/
may be better.
Hugo |