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 使您能够猜测给定数据所编码的编码,或者至少尝试猜测。
默认情况下,它仅检查带有 BOM 的 ascii、utf8 和 UTF-16/32。
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
会刷新当前嫌疑列表,而 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/);
当您对嫌疑人列表感到满意时,您现在可以
my $utf8 = Encode::decode("Guess", $data);
但如果
有两个或更多嫌疑人
没有嫌疑人
那么您应该尝试这样做;
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,还可以选择获取嫌疑人列表。可选的嫌疑人列表不会反映到内部嫌疑人列表中。
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 之一是唯一的嫌疑人(除了 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 拆分为多行,然后尝试为每个嫌疑人解码该行。它会一直进行下去,直到嫌疑人列表中只剩下一个编码。在大多数情况下,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/);
不要放置太多嫌疑人!不要尝试这样做!
my $decoder = guess_encoding($data,
Encode->encodings(":all"));
毕竟,这只是一个猜测。在涉及编码时,您应该始终明确。但是,有一些环境(尤其是日语环境)必须进行猜测编码。请谨慎使用此模块。
Encode::Guess 在 EBCDIC 平台上不起作用。