Perl Encode::Guess 不知道简单的 ISO-8859-1/latin1 字符?
Perl Encode::Guess doesn't know about simple ISO-8859-1/latin1 characters?
我正在尝试找出许多输入字符串的编码,有些是 UTF-8,有些是 ISO-8859-1。不幸的是。
我将 Perl 与 Encode::Guess
一起使用,我很惊讶地发现它无法处理简单的 Latin1 编码。我正在使用 Encode::Guess 文档中的解码示例。
我一直在读取文件,但我也可以对字符串进行硬编码以获得相同的错误:
use Encode::Guess;
my $data = "The name \xc5sa is Swedish\n";
my $enc = guess_encoding($data,qw/latin1 utf8 ascii/);
ref($enc) or die "Can't guess: $enc\nFOR: $data";
然后我得到:
Can't guess: No appropriate encodings found!
FOR: The name �sa is Swedish
尽管在我的编辑器中,我看到第一个字符是 Aring 的“Åsa”。
Perl 是否预先确定了编码,因为它是一个字符串而不是一组打包的二进制数据,这就是破坏它的原因?
我在读取文件时尝试了 use open ":encoding(Latin1)";
,错误消失了,但它猜测编码是 UTF-8。无论如何,该文件逐行混合了 UTF-8 和 Latin1,所以我想 运行 Encode::Guess
每行。
我也尝试 binmode
文件句柄,但仍然看到错误。
这一行
my $enc = guess_encoding($data,/latin1 utf8 ascii/);
应该是
my $enc = guess_encoding($data,qw/latin1 utf8 ascii/);
^^
你的程序有问题。参数 /latin1 utf8 ascii/
正在尝试将正则表达式模式应用于(未定义的)变量 $_
。您会看到一条警告消息
Use of uninitialized value $_ in pattern match (m//)
你真的应该告诉我们
请注意,use open ":encoding(Latin1)"
与在您打开文件句柄时对每个文件句柄应用 binmode $fh, ":encoding(Latin1)"
相同,并且会在您读取数据时尝试将数据解码为 Latin1。结果将是一个字符串,该字符串对文件中的 Latin1 字符使用 Perl 的内部编码。如果其中一些是 UTF-8,那将是灾难性的。 A 环字符的 UTF-8 编码是两个字节 C3
85
,它被视为 Latin1,是一个波浪号后跟一个非法字符
这应该适合你
use strict;
use warnings 'all';
use feature 'say';
use Encode::Guess;
for my $data (
"The name \xC5sa is Swedish\n",
"The name \N{U+00C5}sa is Swedish\n" ) {
my $enc = guess_encoding($data, qw/ latin1 utf8 ascii /);
ref($enc) or die "Can't guess: $enc\nFOR: $data";
say $enc->name;
}
输出
iso-8859-1
utf8
更新
我强烈推荐 Grant McLean 的 Encoding::FixLatin
模块,它可以满足您的所有需求。它还将涵盖在一行中使用两种编码的情况
该程序处理一个使用 Latin1
编码的字符串和另一个使用 UTF-8
编码的字符串。使用 fix_latin
处理后,两者都可以毫无问题地打印出来
use strict;
use warnings 'all';
use feature 'say';
use open qw/ :std :encoding(UTF-8) /;
use Encoding::FixLatin 'fix_latin';
for my $data (
"The name \xC5sa is Swedish\n",
"And so is Asbj\N{U+00F6}rn\n" ) {
my $utf8 = fix_latin($data);
print $utf8;
}
输出
The name Åsa is Swedish
And so is Asbjörn
最好使用此技术一次性读取和处理整个文件。除非文件很大并且会导致内存问题,否则逐行读取文件没有意义
我正在尝试找出许多输入字符串的编码,有些是 UTF-8,有些是 ISO-8859-1。不幸的是。
我将 Perl 与 Encode::Guess
一起使用,我很惊讶地发现它无法处理简单的 Latin1 编码。我正在使用 Encode::Guess 文档中的解码示例。
我一直在读取文件,但我也可以对字符串进行硬编码以获得相同的错误:
use Encode::Guess;
my $data = "The name \xc5sa is Swedish\n";
my $enc = guess_encoding($data,qw/latin1 utf8 ascii/);
ref($enc) or die "Can't guess: $enc\nFOR: $data";
然后我得到:
Can't guess: No appropriate encodings found!
FOR: The name �sa is Swedish
尽管在我的编辑器中,我看到第一个字符是 Aring 的“Åsa”。
Perl 是否预先确定了编码,因为它是一个字符串而不是一组打包的二进制数据,这就是破坏它的原因?
我在读取文件时尝试了 use open ":encoding(Latin1)";
,错误消失了,但它猜测编码是 UTF-8。无论如何,该文件逐行混合了 UTF-8 和 Latin1,所以我想 运行 Encode::Guess
每行。
我也尝试 binmode
文件句柄,但仍然看到错误。
这一行
my $enc = guess_encoding($data,/latin1 utf8 ascii/);
应该是
my $enc = guess_encoding($data,qw/latin1 utf8 ascii/);
^^
你的程序有问题。参数 /latin1 utf8 ascii/
正在尝试将正则表达式模式应用于(未定义的)变量 $_
。您会看到一条警告消息
Use of uninitialized value $_ in pattern match (m//)
你真的应该告诉我们
请注意,use open ":encoding(Latin1)"
与在您打开文件句柄时对每个文件句柄应用 binmode $fh, ":encoding(Latin1)"
相同,并且会在您读取数据时尝试将数据解码为 Latin1。结果将是一个字符串,该字符串对文件中的 Latin1 字符使用 Perl 的内部编码。如果其中一些是 UTF-8,那将是灾难性的。 A 环字符的 UTF-8 编码是两个字节 C3
85
,它被视为 Latin1,是一个波浪号后跟一个非法字符
这应该适合你
use strict;
use warnings 'all';
use feature 'say';
use Encode::Guess;
for my $data (
"The name \xC5sa is Swedish\n",
"The name \N{U+00C5}sa is Swedish\n" ) {
my $enc = guess_encoding($data, qw/ latin1 utf8 ascii /);
ref($enc) or die "Can't guess: $enc\nFOR: $data";
say $enc->name;
}
输出
iso-8859-1
utf8
更新
我强烈推荐 Grant McLean 的 Encoding::FixLatin
模块,它可以满足您的所有需求。它还将涵盖在一行中使用两种编码的情况
该程序处理一个使用 Latin1
编码的字符串和另一个使用 UTF-8
编码的字符串。使用 fix_latin
use strict;
use warnings 'all';
use feature 'say';
use open qw/ :std :encoding(UTF-8) /;
use Encoding::FixLatin 'fix_latin';
for my $data (
"The name \xC5sa is Swedish\n",
"And so is Asbj\N{U+00F6}rn\n" ) {
my $utf8 = fix_latin($data);
print $utf8;
}
输出
The name Åsa is Swedish
And so is Asbjörn
最好使用此技术一次性读取和处理整个文件。除非文件很大并且会导致内存问题,否则逐行读取文件没有意义