Unicode-готовый wordsearch - Вопрос - PullRequest
4 голосов
/ 13 июля 2011

Этот код в порядке? Я не имею понятия, какую форму нормализации мне следует использовать (единственное, что я заметил, это 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 Ответ

3 голосов
/ 16 августа 2011

Вау !! Я не могу поверить, что никто не ответил на это. Это супер отличный вопрос. Ты тоже почти все правильно понял. Мне нравится, что вы используете Unicode :: Collate :: Locale и Unicode :: GCString. Молодец!

Причина, по которой вы получаете «неправильный» вывод, заключается в том, что вы не используете метод columns класса Unicode :: GCString для определения ширины печати материала, который вы печатаете.

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;
 }

Видите, как это работает?

Теперь нормализация не имеет значения. Не обращайте внимания на старый комментарий Керрека. Это очень неправильно. УЦА специально разработан таким образом, чтобы не допустить нормализации. Вы должны наклониться назад, чтобы ввернуть, чем вверх, например, передав normalization => undef в конструктор на случай, если вы захотите использовать его метод gmatch или что-то подобное.

...