Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a char variable in tr///

Tags:

perl

I am trying to count the characters in a string and found an easy solution counting a single character using the tr operator. Now I want to do this with every character from a to z. The following solution doesn't work because tr/// matches every character.

my @chars = ('a' .. 'z');
foreach my $c (@chars)
{
    $count{$c} = ($text =~ tr/$c//);
}

How do I correctly use the char variable in tr///?

like image 351
André Stannek Avatar asked Jul 10 '12 14:07

André Stannek


2 Answers

tr/// doesn't work with variables unless you wrap it in an eval

But there is a nicer way to do this:

$count{$_} = () = $text =~ /$_/g for 'a' .. 'z';

For the TIMTOWTDI:

$count{$_}++ for grep /[a-z]/i, split //, $text;
like image 94
Zaid Avatar answered Oct 07 '22 22:10

Zaid


tr doesn't support variable interpolation (neither in the search list nor in the replacement list). If you want to use variables, you must use eval():

$count{$c} = eval "\$text =~ tr/$c/$c/";

That said, a more efficient (and secure) approach would be to simply iterate over the characters in the string and increment counters for each character, e.g.:

my %count = map { $_ => 0 } 'a' .. 'z';

for my $char (split //, $text) {
    $count{$char}++ if defined $count{$char};
}
like image 37
Eugene Yarmash Avatar answered Oct 07 '22 23:10

Eugene Yarmash