Encode モジュールを用いた日本語処理関連メモ
2006-10-11


とりあえず見ておけ的リンク↓

で、関連する情報についていくつかメモ。

use utf8 な環境でファイル名を指定する場合の書法

ファイル名に日本語が含まれていたりすると、そのままでは確実に失敗するので、ファイル名の指定に encode() をかます必要がある。以下、サンプルコード。

use strict;
use utf8;

use Encode;
use Encode::Guess qw(euc-jp cp932 7bit-jis);

binmode STDOUT, ':encoding(cp932)';
binmode STDERR, ':encoding(cp932)';

my $file = 'テストファイル.txt';

-e encode('cp932', $file)       or die "$file なんてファイルねっす";

open fin, '<:encoding(Guess)', encode('cp932', $file)
        or die '失敗しますた';

while (<fin>){
        print $_;
}

キャラクターセットの指定が cp932 になっているのは、このテストコードを書いた環境が Windows XP で ActivePerl 向けだから。それ以外の環境でも動かすことを想定してプログラムを書く場合は、$^O 変数を見てプラットフォームを特定したり、環境変数 LANG を参照してみたりして特定する必要があるかと思われ。つか、Windows で Perl からシステムロケールを知るにはどうすればいいんだ? レジストリ? ('A`)マンドクセ

キャラクターセットを自動認識したい

で、上記のサンプルコードにもさり気に忍ばせてあるんだけれどもw、Encode::Guess[LINK] とやらを use してやることによってキャラクターセットを自動認識させることができる。

しかしこいつには問題もある。まぁシグネチャ付きの UTF-8 (言っておくが UTF-8 のシグネチャは大本営も BOM と呼んでいるが BOM ではないぞ、バイトオーダー関係ないし) なんてそもそも Perl とは水と油の関係のようなものを持ち出されても困ってしまうわけなんだろうが (こちらとしては対応してくれていない現状こそむしろ困っちゃってるわけだが)、それ以前にそもそも曖昧で判別できないようなケースに出くわすと、適当にどっちかに倒して突き進んでくれればいいようなものを、あろうことか例外を起こして処理を投げ出してしまうのである。

例えば、以下のテキストを Shift_JIS で保存したものを上記のプログラムに食わせてみると、

This file is dummy text for test.
abababababa
ubububububu
このファイルはテスト用です。
m9(^A^)プギャー
うひゃひゃひゃ

コマンドプロンプト上での結果は以下の通りとなる。

C:\foo\bar>perl test.pl
This file is dummy text for test.
abababababa
ubububububu
このファイルはテスト用です。
euc-jp or cp932 at test4.pl line 18

C:\foo\bar>

jcode.pl とかにおいても Shift_JIS の半角カナは euc-jp との判別ができずに文字化けしてしまうということはよくあったわけだが、それでもまぁ化けたら化けたなりにデータとして突っ込んでおけばいいか的な程よい諦めと安心感はあった。が、プログラムが強制的に止まってしまうとなれば話は別だ。

ちなみに open 時には自動認識を指定せずに、print する直前で decode するようにしても結果は同じである。

use strict;
use utf8;

use Encode;
use Encode::Guess qw(euc-jp cp932 7bit-jis);

binmode STDOUT, ':encoding(cp932)';
binmode STDERR, ':encoding(cp932)';

my $file = 'テストファイル.txt';

-e encode('cp932', $file)       or die "$file なんてファイルねっす";

open fin, '<:raw', encode('cp932', $file)
        or die '失敗しますた';

while (<fin>){
        print decode('Guess', $_);      # これでも結局落ちる
}
C:\foo\bar>perl test.pl
This file is dummy text for test.
abababababa
ubububububu
このファイルはテスト用です。
euc-jp or cp932 at C:/Perl/lib/Encode.pm line 164

C:\foo\bar>

で、解決策としては、eval を用いた、若干キモチワルイコードということになる。なんだかなぁ。。。




続きを読む

[設計・開発]
[個人的メモ]

コメント(全0件)
コメントをする


記事を書く
powered by ASAHIネット