【问题标题】:Unicode-ready wordsearch - QuestionUnicode-ready wordsearch - 问题
【发布时间】:2011-10-04 11:48:19
【问题描述】:

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

【问题讨论】:

  • 您使用哪个规范化并不重要,只要您对所有要比较的字符串使用相同的规范化!跨度>
  • @Kerrek 这是不正确的。 Unicode::Collat​​e(及其子类 U::C::Locale)和 Unicode::GCString 都是专门设计的,因此规范化无关紧要

标签: perl unicode word collate unicode-normalization


【解决方案1】:

哇!!我不敢相信没有人回答这个问题。这是一个非常棒的问题。你也几乎做对了。我喜欢你使用 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 方法或类似的方法。

【讨论】:

  • 但是,如果我在计数之前进行标准化,那么字数统计 ($hash{key}++) 会有所不同吗?
猜你喜欢
  • 2014-05-03
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
  • 2010-12-26
  • 2014-02-08
  • 2011-11-09
  • 2013-02-12
  • 2010-12-16
相关资源
最近更新 更多