2015-12-23 12 views
5

私はLinuxでperlシェルでサブを書くのではなく、オカレンスをカウントする良い方法が必要だと感じました。 (あなたの4本のラインと比較して)文字列内の文字の出現箇所を数える文字列内の文字の出現を数える良い方法はありますか?

#/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; 
} 
+1

ロバート、おかげで、私は今後の文法チェックを追加します。 – Gang

答えて

2

から美しい *バッシュ/のCoreutils/Grepのワンライナーで:

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

それとも

$ grep -o "$char" <<< "$str" | wc -l 
8 

最初のものは、サブだけである場合にのみ機能します1文字長い。 2番目の部分は、部分文字列が重複していない場合にのみ機能します。

*実際にはありません。

+0

はどちらもうまく動作し、私はツールボックスに追加しました。 – Gang

+1

@gliang:これはBashの 'split //'のようなものですが、私は最近もそれを発見しました。あなたがそれらが有用であるとうれしい! –

2

toolicが正しい答えを示していますが、プログラムを再利用できるようにハードコーディングしないことを検討することもできます。

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] || [email protected]) { # 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"; 

これにより、プログラムを使用して、文字列、文字列、文字列、ファイル、または標準入力の出現をカウントできます。

count.pl needles haystack.txt 
some_process | count.pl foo 
count.pl x xyzzy 
+0

gmsは何ですか? g - すべての出現のために、mはマッチのために、sは? – Gang

+1

@gliang: "文字列を1行として扱う"、つまり '.'は改行にマッチします。通常はそうではありません。http://perldoc.perl.org/perlre.html#Modifiers –

+0

ベンジャミン、ありがとうございますそれは私が思っていたものではありません。私は再びその文書を読むでしょう。 – Gang

4

文字が一定であれば、次は最高です:

my $count = $str =~ tr/y//; 

文字が可変である場合、私は次のように使用したい:例えば

my $count = length($str =~ s/[^\Q$char\E]//rg); 

私は」もしPerlが5.14より古いバージョンとの互換性を望むのであれば、次のコードを使用してください(遅くてメモリを増やすので):

my $count =() = $str =~ /\Q$char/g; 

以下は何のメモリを使用しませんが、少し遅いかもしれません:

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

あなたは素晴らしいです、perlはいつも私に驚きを与える!、ありがとう。 – Gang

関連する問題