【发布时间】:2019-04-08 13:14:45
【问题描述】:
我有一个 perl 存储文件,其中(当使用 Dumper 的 dumper 时)其中包含以下字符串:
my $str1 = "1 = educa\x{c3}\x{a7}\x{c3}\x{a3}o";
my $str2 = "2 = educa\x{e7}\x{e3}o";
我一直在尝试制定一个合理的策略来输出 UTF8(另请参阅 perl Encode::Guess with and without hints - detecting utf8)。
让我继续上面的 perl 代码,并得到一些声明:
use 5.18.2;
use Encode qw( encode_utf8 decode_utf8 from_to encode decode);
use Encode::Guess;
use Encoding::FixLatin qw(fix_latin);
sub sayStrings() {
say fixEnc($_[0]);
say fixEnc($_[1],'hint');
say "";
};
sub fixEnc() {
my $data = $_[0];
my $enc = "";
if ($_[1]) {
$enc = guess_encoding($data, qw/utf8 latin-1/);
} else {
$enc = guess_encoding($data);
};
if (!ref($enc)) {
return "ERROR: Can't guess: $enc for $data";
} else {
my $flag1a = utf8::is_utf8($data);
my $flag2a = utf8::valid($data);
$data .= "; encoding: ".$enc->name.", is_utf8=$flag1a, valid=$flag2a";
return $data;
};
};
现在回答问题!我将用各种 sn-ps 来补充该代码。
say "Question 1";
&sayStrings($str1, $str2);
和
use open IO => ':encoding(UTF-8)';
say "raw";
&sayStrings($str1, $str2);
两者都给出:
Question 1
1 = educação; encoding: utf8, is_utf8=, valid=1
2 = educa??o; encoding: iso-8859-1, is_utf8=, valid=1
问题 1A:use open IO => ':encoding(UTF-8)'; 什么都不做?我想我的系统已经设置为 UTF8。对吗?
问题1B:为什么2中的字符显示不正确?编码被正确检测到,但也许当字符串以 UTF 输出时,“çã”变成系统不知道的 UTF 字符(或者不存在)?
现在回答问题 2:
use open IO => ':encoding(UTF-8)',':std';
say "Question 2";
&sayStrings($str1, $str2);
给予:
Question 2
1 = educação; encoding: utf8, is_utf8=, valid=1
2 = educação; encoding: iso-8859-1, is_utf8=, valid=1
问题 2:为什么这样可以让 latin-1 字符串正确显示,但会破坏 UTF8 字符串? (即似乎通过添加 :std,str1 中的字符序列被解释为 latin-1,而不是 UFT8,请参阅perl Encode::Guess with and without hints - detecting utf8)。这是为什么呢?
问题 3:
use open IO => ':encoding(UTF-8)',':std';
say "fix_latin";
&sayStrings(&fix_latin($str1), &fix_latin($str2));
给予
fix_latin
1 = educação; encoding: utf8, is_utf8=1, valid=1
2 = educação; encoding: utf8, is_utf8=1, valid=1
问题3:我猜fix_latin表示字符串是utf8,所以字符串打印正确。因此,对于将字符串标记为 utf8 和 binmode,显然有些我不理解。这是什么?
非常感谢!
(P.S. 已尝试阅读有关此的文档,但是是的,请发送可以解释这一点的链接 - 最好用清晰的语言和大量示例...)
【问题讨论】: