Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 有没有更好的方法来计算字符串中字符的出现次数?_Perl_Sh - Fatal编程技术网

Perl 有没有更好的方法来计算字符串中字符的出现次数?

Perl 有没有更好的方法来计算字符串中字符的出现次数?,perl,sh,Perl,Sh,我觉得必须有更好的方法来计算发生率,而不是用perl编写sub,用Linux编写shell #/usr/bin/perl -w use strict; return 1 unless $0 eq __FILE__; main() if $0 eq __FILE__; sub main{ my $str = "ru8xysyyyyyyysss6s5s"; my $char = "y"; my $count = count_occurrence($str, $char);

我觉得必须有更好的方法来计算发生率,而不是用perl编写sub,用Linux编写shell

#/usr/bin/perl -w
use strict;
return 1 unless $0 eq __FILE__;
main() if $0 eq __FILE__;
sub main{
    my $str = "ru8xysyyyyyyysss6s5s";
    my $char = "y";
    my $count = count_occurrence($str, $char);
    print "count<$count> of <$char> in <$str>\n";
}
sub count_occurrence{
    my ($str, $char) = @_;
    my $len = length($str);
    $str =~ s/$char//g;
    my $len_new = length($str);
    my $count = $len - $len_new;
    return $count;
}
#/usr/bin/perl-w
严格使用;
返回1,除非$0 eq\u文件;
main()如果$0 eq\u文件;
副总管{
my$str=“ru8xysyyyyyysss6s5s”;
我的$char=“y”;
my$count=count\u事件($str,$char);
打印“输入的计数”\n;
}
子计数{
我的($str,$char)=@;
my$len=长度($str);
$str=~s/$char//g;
my$len_new=长度($str);
my$count=$len-$len_new;
返回$count;
}

在Perl中,计算字符串中某个字符的出现次数只需一行即可(与您的4行相比)。不需要sub(尽管将功能封装在sub中没有什么错)。从

使用警告;
严格使用;
my$str=“ru8xysyyyyyysss6s5s”;
我的$char=“y”;
我的$count=()=$str=~/\Q$char/g;
打印“输入的计数”\n;
在一行漂亮的*Bash/Coreutils/Grep中:

$ str=ru8xysyyyyyyysss6s5s
$ char=y
$ fold -w 1 <<< "$str" | grep -c "$char"
8
$str=ru8xysyyyyyysss6s5s
$char=y
$WORK-W 1 

给出了正确的答案,但是您可以考虑不要硬编码您的值以使程序可重用。

use strict;
use warnings;

die "Usage: $0 <text> <characters>" if @ARGV < 1;
my $search = shift;                    # the string you are looking for
my $str;                               # the input string
if (@ARGV && -e $ARGV[0] || !@ARGV) {  # if str is file, or there is no str
    local $/;                          # slurp input
    $str = <>;                         # use diamond operator
} else {                               # else just use the string
    $str = shift;
}
my $count = () = $str =~ /\Q$search\E/gms;
print "Found $count of '$search' in '$str'\n";

如果字符为常量,则最好使用以下选项:

my $count = $str =~ tr/y//;
如果字符是可变的,我将使用以下命令:

my $count = length( $str =~ s/[^\Q$char\E]//rg );
如果我想与5.14以上版本的Perl兼容,我只会使用以下内容(因为它速度较慢,占用更多内存):

以下内容不使用内存,但可能有点慢:

my $count = 0;
++$count while $str =~ /\Q$char/g;

两个都很好,我把它们添加到我的工具箱中,第一次听到cmd折叠,谢谢@gliang:有点像Bash的
split/
,我也是最近才发现的。很高兴你发现它们有用!gms是干什么的?g-对于所有出现的情况,m表示匹配,s表示?@gliang:“将字符串视为单行”,即,
匹配新行,通常不会匹配,请参见Benjamin,谢谢,这不是我所认为的。我会再看一遍文档。@gliang不,
m
是多行的,这意味着换行符由
^
$
(以及等效项)匹配,并且像Benjamin所说的
s
使
也匹配换行符。在您的示例中并不严格需要它们,
\Q
排除了
元字符的使用。但由于我们不知道您的输入是什么,这是一种更安全的方法。
my $count = $str =~ tr/y//;
my $count = length( $str =~ s/[^\Q$char\E]//rg );
my $count = () = $str =~ /\Q$char/g;
my $count = 0;
++$count while $str =~ /\Q$char/g;