6

tr文字列内の文字を数えようとしていますが、演算子を使用して1文字を数える簡単な解決策を見つけました。今、私はこれをaからzまでのすべての文字で実行したいと思います。tr///次の解決策は、すべての文字に一致するため機能しません。

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

でchar変数を正しく使用するにはどうすればよいtr///ですか?

4

6 に答える 6

7

tr///変数でラップしない限り、変数は機能しませんeval

しかし、これを行うためのより良い方法があります:

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

TIMTOWTDIの場合:

$count{$_}++ for grep /[a-z]/i, split //, $text;
于 2012-07-10T14:12:26.497 に答える
6

tr変数の補間をサポートしていません(検索リストでも置換リストでも)。変数を使用する場合は、次を使用する必要がありますeval()

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

そうは言っても、より効率的な(そして安全な)アプローチは、文字列内の文字を単純に反復し、各文字のカウンターをインクリメントすることです。例:

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

for my $char (split //, $text) {
    $count{$char}++ if defined $count{$char};
}
于 2012-07-10T14:13:49.697 に答える
3

のperldocを見るtr/SEARCHLIST/REPLACEMENTLIST/cdsrと、セクションの一番下に次のように表示されます。

文字変換テーブルはコンパイル時に作成されるため、SEARCHLISTもREPLACEMENTLISTも二重引用符の補間を受けません。つまり、変数を使用する場合は、eval()を使用する必要があります。

eval "tr/$oldlist/$newlist/";
die $@ if $@;
eval "tr/$oldlist/$newlist/, 1" or die $@;

したがって、新しいSEARCHLISTを生成するには評価が必要になります。

これは非常に非効率的になります...コードはきれいに感じるかもしれませんが、完全な文字列を26回処理しています。また、大文字は数えていません。

文字列を1回ステップ実行し、見つかった文字ごとにカウンターをインクリメントする方がよいでしょう。

于 2012-07-10T14:13:38.703 に答える
1

perlopのドキュメントから:

tr/AAA/XYZ/

AからXに音訳します。

文字変換テーブルはコンパイル時に作成されるため、SEARCHLISTもREPLACEMENTLISTも二重引用符の補間を受けません。つまり、変数を使用する場合は、eval()を使用する必要があります。

s///または、次のように演算子を使用することもできます。

foreach my $c (@chars) {
   $count{$c} += ($text =~ s/$c//g);
}
于 2012-07-10T14:13:24.927 に答える
1

http://www.perlmonks.org/?node_id=446003に基づいていくつかの変更を加えた私のソリューション

sub lowerLetters {
    my $string = shift;
    my %table;
    @table{split //, $letters_uc} = split //, $letters_lc;
    my $table_re = join '|', map { quotemeta } reverse sort keys %table;
    $string =~ s/($table_re)/$table{$1}/g;
    return if not defined $string;
    return $string;
}
于 2013-10-09T09:26:57.450 に答える
1

代わりに使用することをお勧めしますs。置換はよりもはるかに強力ですtr

私の解決策:

$count{$c} =~ s/\$search/$replace/g;

g最後に「グローバルに使用する」という意味です。

見る:

于 2020-08-18T10:24:22.980 に答える