2011-07-13 35 views
4

此代碼是否可用?我真的不知道我應該使用哪種規範化形式(我注意到的唯一情況是NFD我得到了錯誤的輸出)。Unicode-ready wordsearch - 問題

#!/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

只要您對比較的所有字符串使用_same_ one,那麼使用_which_標準化並不重要! –

+1

@Kerrek這是不正確的。 Unicode :: Collat​​e(及其子類U :: C :: Locale)和Unicode :: GCString都是專門設計的,因此規範化**無關緊要。 – tchrist

回答

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等等。

+0

但是,如果我在計數之前進行歸一化,那麼它對字數計數($ hash {key} ++)有所不同? –

+0

@sid是的,你是對的,它的確如此。 – tchrist