Encode::Guess -- 從資料猜測編碼
# if you are sure $data won't contain anything bogus
use Encode;
use Encode::Guess qw/euc-jp shiftjis 7bit-jis/;
my $utf8 = decode("Guess", $data);
my $data = encode("Guess", $utf8); # this doesn't work!
# more elaborate way
use Encode::Guess;
my $enc = guess_encoding($data, qw/euc-jp shiftjis 7bit-jis/);
ref($enc) or die "Can't guess: $enc"; # trap error this way
$utf8 = $enc->decode($data);
# or
$utf8 = decode($enc->name, $data)
Encode::Guess 可讓您猜測給定資料的編碼,或至少嘗試猜測。
預設只檢查 ascii、utf8 和 UTF-16/32(含 BOM)。
use Encode::Guess; # ascii/utf8/BOMed UTF
要更實用地使用它,您必須提供要檢查的編碼名稱(如下所示的可疑對象)。可疑對象的名稱可以是正規名稱或別名。
注意事項:與 UTF-(16|32) 不同,utf8 中的 BOM 並不會自動移除。
# tries all major Japanese Encodings as well
use Encode::Guess qw/euc-jp shiftjis 7bit-jis/;
如果將 $Encode::Guess::NoUTFAutoGuess
變數設定為 true 值,則不會對 UTF8/16/32 套用任何啟發式,結果將僅限於可疑對象和 ascii
。
您也可以透過 set_suspects
方法變更內部可疑對象清單。
use Encode::Guess;
Encode::Guess->set_suspects(qw/euc-jp shiftjis 7bit-jis/);
或者您可以使用 add_suspects
方法。不同之處在於 set_suspects
會清除目前的 suspects 清單,而 add_suspects
則會新增。
use Encode::Guess;
Encode::Guess->add_suspects(qw/euc-jp shiftjis 7bit-jis/);
# now the suspects are euc-jp,shiftjis,7bit-jis, AND
# euc-kr,euc-cn, and big5-eten
Encode::Guess->add_suspects(qw/euc-kr euc-cn big5-eten/);
當您滿意 suspects 清單時,現在您可以
my $utf8 = Encode::decode("Guess", $data);
但如果發生下列情況,它會 croak
兩個或更多 suspects 仍然存在
沒有 suspects 剩餘
因此,您應該嘗試以下方法;
my $decoder = Encode::Guess->guess($data);
成功時,$decoder 是在 Encode::Encoding 中記載的文件。因此,您現在可以執行以下動作;
my $utf8 = $decoder->decode($data);
失敗時,$decoder 現在包含錯誤訊息,因此整個過程如下;
my $decoder = Encode::Guess->guess($data);
die $decoder unless ref($decoder);
my $utf8 = $decoder->decode($data);
您也可以嘗試 guess_encoding
函式,它預設會匯出。它會檢查 $data,而且也會選用 suspects 清單。選用的 suspect 清單不會反映在內部 suspects 清單中。
my $decoder = guess_encoding($data, qw/euc-jp euc-kr euc-cn/);
die $decoder unless ref($decoder);
my $utf8 = $decoder->decode($data);
# check only ascii, utf8 and UTF-(16|32) with BOM
my $decoder = guess_encoding($data);
由於使用的演算法,ISO-8859 系列和其他單位元組編碼無法正常運作,除非 ISO-8859 之一是唯一的 suspect(除了 ascii 和 utf8)。
use Encode::Guess;
# perhaps ok
my $decoder = guess_encoding($data, 'latin1');
# definitely NOT ok
my $decoder = guess_encoding($data, qw/latin1 greek/);
原因是 Encode::Guess 透過嘗試和錯誤來猜測編碼。它會先將 $data 分割成多行,然後嘗試為每個 suspect 解碼該行。它會持續進行,直到所有編碼都從 suspects 清單中移除,只留下一個。ISO-8859 系列在大部分情況下都太成功了(因為它填滿了 \x00-\xff 中的幾乎所有碼點)。
請勿混用國家標準編碼和對應的廠商編碼。
# a very bad idea
my $decoder
= guess_encoding($data, qw/shiftjis MacJapanese cp932/);
原因是廠商編碼通常是國家標準的超集,因此在大部分情況下會變得太過模稜兩可。
另一方面,混用各種國家標準編碼會自動運作,除非 $data 太短,無法猜測。
# This is ok if $data is long enough
my $decoder =
guess_encoding($data, qw/euc-cn
euc-jp shiftjis 7bit-jis
euc-kr
big5-eten/);
請勿放入太多 suspects!請勿嘗試類似下列的動作!
my $decoder = guess_encoding($data,
Encode->encodings(":all"));
畢竟,這只是一個猜測。在編碼時,您應該始終明確。但有些環境,尤其是日文環境,猜測編碼是必須的。請小心使用此模組。
Encode::Guess 不適用於 EBCDIC 平台。