4

このコードは大丈夫ですか?私は実際にどの正規化形式を使用すべきかについての手がかりを持っていません(私が気付いた唯一のことはNFD、間違った出力を取得することです)。

#!/usr/local/bin/perl
use warnings;
use 5.014;
use utf8;
binmode STDOUT, ':encoding(utf-8)';

use Unicode::Normalize;
use Unicode::Collate::Locale;
use Unicode::GCString;

my $text = "my taxt täxt";
my %hash;

while ( $text =~ m/(\p{Alphabetic}+(?:'\p{Alphabetic}+)?)/g ) { #'
    my $word = $1;
    my $NFC_word = NFC( $word );
    $hash{$NFC_word}++;
}

my $collator = Unicode::Collate::Locale->new( locale => 'DE' ); 

for my $word ( $collator->sort( keys %hash ) ) {
    my $gcword = Unicode::GCString->new( $word );
    printf "%-10.10s : %5d\n", $gcword, $hash{$word};
}
4

1 に答える 1

3

わお!!誰もこれに答えなかったなんて信じられない。それは非常に素晴らしい質問です。あなたもほぼ正しかった。Unicode :: Collat​​e::LocaleとUnicode::GCStringを使用しているのが好きです。よかったね!

「間違った」出力が表示される理由は、Unicode::GCStringクラスのcolumnsメソッドを使用して印刷するものの印刷幅を決定していないためです。

printfは非常に愚かで、列ではなくコードポイントをカウントするだけなので、GCS列を考慮に入れた独自のパッド関数を作成する必要があります。たとえば、これを書く代わりに、手動でそれを行うには:

 printf "%-10.10s", $gstring;

あなたはこれを書かなければなりません:

 $colwidth = $gcstring->columns();
 if ($colwidth > 10) {
      print $gcstring->substr(0,10);
 } else {
     print " " x (10 - $colwidth);
     print $gcstring;
 }

それがどのように機能するか見てみましょう。

これで、正規化は重要ではありません。Kerrekの古いコメントは無視してください。それは非常に間違っています。UCAは、正規化が問題に入らないように特別に設計されています。そのメソッドなどnormalization => undefを使用する場合に備えてコンストラクターに渡すなど、上向きよりも後ろ向きに曲げてねじ込む必要があります。gmatch

于 2011-08-16T01:51:41.103 に答える