这段代码好吗?我真的不知道我应该使用哪种规范化形式(我唯一注意到的是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};
}
答案 0 :(得分:3)
哇!!我无法相信没有人回答这个问题。这是一个非常好的问题。你几乎也是对的。我喜欢你使用Unicode :: Collate :: Locale和Unicode :: GCString。对你有好处!
您输出“错误”的原因是因为您没有使用Unicode :: GCString类的columns
方法来确定要打印的内容的打印宽度。
printf
非常愚蠢,只计算代码点,而不是列数,因此您必须编写自己的pad函数,将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
方法或其他方法。