如何计算Perl中的字符?

时间:2010-09-28 14:25:55

标签: regex perl charactercount

我有以下Perl脚本计算字符串中的Fs和Ts的数量:

my $str = "GGGFFEEIIEETTGGG";
my $ft_count = 0;
$ft_count++ while($str =~ m/[FT]/g);
print "$ft_count\n";

是否有更简洁的方法来计算(换句话说,将第2行和第3行合并)?

4 个答案:

答案 0 :(得分:25)

my $ft_count = $str =~ tr/FT//;

请参阅perlop

  

如果REPLACEMENTLIST为空,则为   SEARCHLIST被复制。后者对于计数很有用   班级中的人物......

  $cnt = $sky =~ tr/*/*/;     # count the stars in $sky
  $cnt = tr/0-9//;            # count the digits in $_

这是一个基准:

use strict; use warnings;

use Benchmark qw( cmpthese );

my ($x, $y) = ("GGGFFEEIIEETTGGG" x 1000) x 2;

cmpthese -5, {
    'tr' => sub {
        my $cnt = $x =~ tr/FT//;
    },
    'm' => sub {
        my $cnt = ()= $y =~ m/[FT]/g;
    },
};
        Rate     tr      m
     Rate     m    tr
m   108/s    --  -99%
tr 8118/s 7440%    --

使用32位Windows XP上的ActiveState Perl 5.10.1.1006。

的差异似乎更为明显
C:\Temp> c:\opt\strawberry-5.12.1\perl\bin\perl.exe t.pl
      Rate      m     tr
m   88.8/s     --  -100%
tr 25507/s 28631%     --

答案 1 :(得分:8)

是的,您可以使用CountOf secret operator

my $ft_count = ()= $str =~ m/[FT]/g;

答案 2 :(得分:8)

当“m”运算符在列表上下文中执行/ g标志AND时,它返回匹配的子字符串列表。所以另一种方法是:

my @ft_matches = $str =~ m/[FT]/g;
my $ft_count = @ft_matches; # count elements of array

但那仍然是两行。另一个更奇怪的技巧可以缩短它:

my $ft_count = () = $str =~ m/[FT]/g;

“()=”强制“m”在列表上下文中。将具有N个元素的列表分配给零变量列表实际上并不执行任何操作。但是当这个赋值表达式在标量上下文中使用时($ ft_count = ...),右边的“=”运算符会从右侧返回元素的数量 - 正是你想要的

第一次遇到这种情况时非常奇怪,但是“=()=”成语是一个有用的Perl技巧,因为“在列表上下文中进行评估,然后得到列表的大小”。

注意:在处理大字符串时,我没有关于哪些更有效的数据。事实上,我怀疑你的原始代码在这种情况下可能是最好的。

答案 3 :(得分:0)

您可以将第2,3和4行合并为一个:

my $str = "GGGFFEEIIEETTGGG";
print $str =~ s/[FT]//g; #Output 4;