Unicode文字列があり、そのエンコーディングが何であるかわかりません。この文字列がPerlプログラムによって読み取られるとき、Perlが使用するデフォルトのエンコーディングはありますか?もしそうなら、どうすればそれが何であるかを知ることができますか?
入力から非ASCII文字を削除しようとしています。私はそれを行ういくつかのフォーラムでこれを見つけました:
my $line = encode('ascii', normalize('KD', $myutf), sub {$_[0] = ''});
入力エンコーディングが指定されていない場合、上記はどのように機能しますか?次のように指定する必要がありますか?
my $line = encode('ascii', normalize('KD', decode($myutf, 'input-encoding'), sub {$_[0] = ''});
未知のものがどのエンコーディングで使用されているかを見つけるには、試してみるだけです。モジュール Encode :: Detect および Encode :: Guess それを自動化します。 (Encode :: Detectのコンパイルに問題がある場合は、そのフォークを試してください Encode :: Detective 代わりに。)
use Encode::Detect::Detector;
my $unknown = "\x{54}\x{68}\x{69}\x{73}\x{20}\x{79}\x{65}\x{61}\x{72}\x{20}".
"\x{49}\x{20}\x{77}\x{65}\x{6e}\x{74}\x{20}\x{74}\x{6f}\x{20}".
"\x{b1}\x{b1}\x{be}\x{a9}\x{20}\x{50}\x{65}\x{72}\x{6c}\x{20}".
"\x{77}\x{6f}\x{72}\x{6b}\x{73}\x{68}\x{6f}\x{70}\x{2e}";
my $encoding_name = Encode::Detect::Detector::detect($unknown);
print $encoding_name; # gb18030
use Encode;
my $string = decode($encoding_name, $unknown);
encode 'ascii'
は、非ASCII文字を取り除くための不完全な解決策です。すべてが質問マークに置き換えられます。これは損失が大きすぎて役に立ちません。
# Bad example; don't do this.
use utf8;
use Encode;
my $string = 'This year I went to 北京 Perl workshop.';
print encode('ascii', $string); # This year I went to ?? Perl workshop.
読みやすいASCIIテキストが必要な場合は、代わりに Text :: Unicodecode をお勧めします。これも不可逆エンコーディングですが、プレーンなencode
上記。
use utf8;
use Text::Unidecode;
my $string = 'This year I went to 北京 Perl workshop.';
print unidecode($string); # This year I went to Bei Jing Perl workshop.
ただし、支援できる場合は、これらの不可逆エンコーディングを避けてください。後で操作を元に戻したい場合は、PERLQQ
またはXMLCREF
のいずれかを選択してください。
use utf8;
use Encode qw(encode PERLQQ XMLCREF);
my $string = 'This year I went to 北京 Perl workshop.';
print encode('ascii', $string, PERLQQ); # This year I went to \x{5317}\x{4eac} Perl workshop.
print encode('ascii', $string, XMLCREF); # This year I went to 北京 Perl workshop.
Encode モジュールには、これを実行する方法があります。 decode
は、エンコーディングと思われる生のオクテットです。オクテットが有効なエンコーディングを表していない場合、オクテットは爆発し、evalでキャッチします。それ以外の場合は、適切にエンコードされた文字列が返されます。例えば:
use Encode;
my $a_with_ring =
eval { decode( 'UTF-8', "\x6b\xc5", Encode::FB_CROAK ) }
or die "Could not decode string: $@";
これには、同じオクテットシーケンスが複数のエンコーディングで有効になる可能性があるという欠点があります。
これについては、次の Effective Perl Programming、2nd Edition で詳しく説明します。これには、Unicodeの取り扱いに関する章全体が含まれています。でも全部投稿したら出版社は怒るだろうと思います。 :)
JuerdのUnicodeアドバイス 、およびPerlに付属しているUnicodeドキュメントのいくつかもご覧ください。