2

些細なことだと思っていた問題があります。私はドイツ語のアルファベット()からウムラウトを扱わなければなりませんäöü。Unicodeでは、それらを表示する方法はいくつかあるようですが、そのうちの1つは文字の結合です。これらのさまざまな方法を正規化し、すべてを1文字のコードに置き換える必要があります。

このような逸脱したウムラウトは簡単に見つかります。これは文字aouであり、その後にUTF-8文字が続き\uCC88ます。だから私は正規表現で十分だと思いました。

これが私の変換機能で、Encodingパッケージを採用しています。

# This sub can be extended to include more conversions
sub convert {
    local $_;
    $_ = shift;

    $_ = encode( "utf-8", $_ );

    s/u\xcc\x88/ü/g;
    s/a\xcc\x88/ä/g;
    s/o\xcc\x88/ö/g;
    s/U\xcc\x88/Ü/g;
    s/A\xcc\x88/Ä/g;
    s/O\xcc\x88/Ö/g;

    return $_;
}

しかし、結果として出力されるumlautは、このリストにあるものではなく、さらに悪質な文字(現在は4バイトを使用)です。

問題は、Perlの内部形式、実際のUTF-8、およびこのエンコード形式とのジャグリングにあると思います。

置換行を次のように変更することもできます

s/u\xcc\x88/\xc3\xbc/g;
s/a\xcc\x88/\xc3\xa4/g;
s/o\xcc\x88/\xc3\xb6/g;
s/U\xcc\x88/\xc3\x9c/g;
s/A\xcc\x88/\xc3\x84/g;
s/O\xcc\x88/\xc3\x96/g;

役に立たなかった、それらは正しく変換されたが、その後バイトに「\ xC2\xA4」が続く。

何か助けはありますか?

4

1 に答える 1

10

あなたはそれを間違っています:表現レベルで文字をいじる習慣を止めなければなりません。つまり、バイナリデータではなくテキストを扱うときに正規表現のバイトをいじらないでください。

最初のステップは、Perlでのエンコーディングのトピックについて学ぶことです。次の段落で使用する「文字列」という用語を理解するには、これが必要です。

文字列がある場合、それは(分解)構成のさまざまな状態のいずれかにある可能性があります。モジュールUnicode::Normalizeを使用して文字列を変更し、Unicode仕様の同等性と正規化に関する関連する章を読んで、詳細を確認してください。これらは、そのモジュールのドキュメントの下部にリンクされています。

必要だと思いますがNFC、データに対して健全性チェックを実行して、それが本当に意図した結果であるかどうかを確認する必要があります。

use charnames qw(:full);
use Unicode::Normalize qw(NFC);
my $original_character_string = "In des Waldes tiefsten Gr\N{LATIN SMALL LETTER U WITH DIAERESIS}nden ist kein R\N{LATIN SMALL LETTER A}\N{COMBINING DIAERESIS}uber mehr zu finden.";
my $modified_character_string = NFC($original_character_string);
# "In des Waldes tiefsten Gr\x{fc}nden ist kein R\x{e4}uber mehr zu finden."
于 2011-11-23T13:38:04.523 に答える