Perlでutf-8でエンコードされた文字列を処理しています。1つのタスクは、「écrit」などの発音区別符号付きの文字で始まる単語が「elephant」および「England」と同じ文字で始まることを知る方法が必要なことです。私はいくつかの言語で作業するので、一般的な解決策が必要です。インデックス用に文字の見出しを作成しているので、これを知る必要があります。今述べた各単語は「E」の下に保存されます。
これを行う簡単な方法はありますか?
Perlでutf-8でエンコードされた文字列を処理しています。1つのタスクは、「écrit」などの発音区別符号付きの文字で始まる単語が「elephant」および「England」と同じ文字で始まることを知る方法が必要なことです。私はいくつかの言語で作業するので、一般的な解決策が必要です。インデックス用に文字の見出しを作成しているので、これを知る必要があります。今述べた各単語は「E」の下に保存されます。
これを行う簡単な方法はありますか?
Text::Unidecodeが役に立ちます。UnicodeをASCIIに変換します。
$ perl -Mutf8 -e 'use Text::Unidecode; print unidecode("écrit")'
ecrit
文字列の同等性と順序は、照合と呼ばれるものによって決定されます。トリッキーな部分は、それらが言語と文化に依存することです(専門用語は「ロケール」です)。たとえば、øとoは同等であると考えるかもしれませんが、デーンにとっては異なる文字であり、異なる順序で並べる必要があります。
照合を操作するためのPerlモジュールはですUnicode::Collate
。
更新: Perlの組み込みロケールサポートを以下で使用することもできますuse locale
:
use locale;
use POSIX qw(setlocale LC_ALL);
setlocale(LC_ALL, ''); # Set default locale from environment variables
これにより、などのビルトインが作成されsort
、cmp
文字列の順序付けにロケールのルールが使用されます。ただし、注意してください。プログラムのロケールを変更すると、出力で小数点がコンマに変更されるなど、予期しない結果が生じる可能性がありprintf
ます。
更新2: POSIXロケールは明らかにさまざまな方法で壊れています。Unicode::Collate
とを使用したほうがよいでしょうUnicode::Collate::Locale
。
私はあなたが英語の照合規則でソートしていて、アルファベットのテキストを持っていると仮定しています。以下のコードは良いスタートですが、現実の世界はそれよりも複雑です。(たとえば、中国語のテキストには、文脈に応じて異なる辞書式規則があります。たとえば、汎用辞書、カラオケ曲リスト、電子ドアベル名リストなど)質問の情報が非常に少ないため、完璧な解決策を提示できません。
use 5.010;
use utf8;
use Unicode::Collate::Locale 0.96;
use Unicode::Normalize qw(normalize);
my $c = Unicode::Collate::Locale->new(locale => 'en');
say for $c->sort(qw(
eye
egg
estate
etc.
eleven
e.g.
England
ensure
educate
each
equipment
elephant
ex-
ending
écrit
));
say '-' x 40;
for my $word (qw(écrit Ëmëhntëhtt-Rê Ênio ècole Ēadƿeard Ėmma Ędward Ẽfini)) {
say sprintf '%s should be stored under the heading %s',
$word, ucfirst substr normalize('D', $word), 0, 1;
}
__END__
each
écrit
educate
e.g.
egg
elephant
eleven
ending
England
ensure
equipment
estate
etc.
ex-
eye
----------------------------------------
écrit should be stored under the heading E
Ëmëhntëhtt-Rê should be stored under the heading E
Ênio should be stored under the heading E
ècole should be stored under the heading E
Ēadƿeard should be stored under the heading E
Ėmma should be stored under the heading E
Ędward should be stored under the heading E
Ẽfini should be stored under the heading E