18 December 2010

(Perl) Encode::Guessでファイルの文字エンコード形式を判定

Encode モジュールを使って、ファイルのエンコード形式を得る(判定する)方法


#!/usr/bin/perl

use warnings;
use strict;
use utf8;
use Encode::Guess qw/euc-jp shiftjis iso-2022-jp/;

# 一つのエンコードに、二つ以上の選択肢を与えると、「選択できないエラー」が返る
# エンコード形式は Encode::Config.pm 参照
#use Encode::Guess qw/euc-jp shiftjis cp932 iso-2022-jp 7bit-jis/;

use Data::Dumper;

# ファイル名のユーザ入力
print 'input filename : ';
$_ = <STDIN>;
chomp;
unless(-f $_){ die "file not found\n"; }

# ファイルから、改行を無視して、一気に読み込む
open(FH, "<$_") or die("file open error\n");
my $strAllLines = undef;
{
local $/ = undef; # 改行を区切りとして使わない
$strAllLines = <FH>;
}
close(FH);

my $enc = Encode::Guess->guess($strAllLines);

print Data::Dumper->Dumper(\$enc)."\n";
if(ref($enc) eq 'Encode::utf8'){ print("detect : utf8\n"); }
elsif(ref($enc) eq 'Encode::Unicode'){
print("detect : ".$$enc{'Name'}."\n");
}
elsif(ref($enc) eq 'Encode::XS'){
print("detect : ".$enc->mime_name()."\n");
}
elsif(ref($enc) eq 'Encode::JP::JIS7'){
print("detect : ".$$enc{'Name'}."\n");
}
else{
# 二つ以上のエンコードが推定される場合は、$encに文字列が返る
print("unknown (".$enc.")\n");
}

実行結果の例


$ perl detect-encode.pl
input filename : test.txt
$VAR1 = 'Data::Dumper';
$VAR2 = \bless( do{\(my $o = '-1220372128')}, 'Encode::XS' );

detect : Shift_JIS

$ perl detect-encode.pl
input filename : test.txt
$VAR1 = 'Data::Dumper';
$VAR2 = \bless( {
'Name' => 'utf8'
}, 'Encode::utf8' );

detect : utf8

$ perl detect-encode.pl
input filename : test.txt
$VAR1 = 'Data::Dumper';
$VAR2 = \bless( {
'h2z' => 1,
'jis0212' => 0,
'Name' => 'iso-2022-jp'
}, 'Encode::JP::JIS7' );

detect : iso-2022-jp

■ エラーになる例

use Encode::Guess qw/shiftjis cp932/; のように、同じエンコード種別を2つ指定した場合、「二つ以上にマッチした場合」となって、次のような結果になる。


$ perl detect-encode.pl
input filename : test.txt
$VAR1 = 'Data::Dumper';
$VAR2 = \'shiftjis or cp932';

unknown (shiftjis or cp932)