Unicode-ready wordsearch - 问题

时间:2011-07-13 13:01:54

标签: perl unicode word collate unicode-normalization

这段代码好吗?我真的不知道我应该使用哪种规范化形式(我唯一注意到的是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};
}

1 个答案:

答案 0 :(得分:3)

哇!!我无法相信没有人回答这个问题。这是一个非常好的问题。你几乎也是对的。我喜欢你使用Unicode :: Collat​​e :: 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方法或其他方法。