Perl Encode :: Guess不知道简单的ISO-8859-1 / latin1字符?

时间:2016-07-10 05:18:12

标签: perl encoding utf-8 iso-8859-1

我试图找出许多输入字符串的编码,一些是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

虽然在我的编辑中,我看到“Åsa”与Aring作为第一个角色。

Perl是否预先确定了编码,因为它是一个字符串,而不是一组打包的二进制数据,那是什么打破了这个?

当我从文件中读取时,我尝试了use open ":encoding(Latin1)";,错误消失了,但它猜测编码为UTF-8。无论如何,该文件在逐行的基础上混合使用UTF-8和Latin1,因此我想为每一行运行Encode::Guess

我还在文件句柄上尝试了binmode,但仍然看到错误。

2 个答案:

答案 0 :(得分:4)

这一行

my $enc = guess_encoding($data,/latin1 utf8 ascii/);

应该是

my $enc = guess_encoding($data,qw/latin1 utf8 ascii/);
                               ^^

答案 1 :(得分:2)

您的程序有问题。参数/latin1 utf8 ascii/正在尝试将正则表达式模式应用于(未定义的)变量$_。你会看到一条警告信息

  

在模式匹配(m //)

中使用未初始化的值$ _

你真的应该告诉我们

请注意,use open ":encoding(Latin1)"与在打开文件句柄时将binmode $fh, ":encoding(Latin1)"应用于每个文件句柄相同,并会在您阅读时尝试将数据解码为Latin1。结果将是一个字符串,它使用Perl的内部编码来处理文件中的Latin1字符。如果其中一些是UTF-8那么那将是灾难性的。 A-ring字符的UTF-8编码是两个字节C3 85,被视为Latin1,是A-tilde,后跟非法字符

这应该对你有用

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

最好使用这种技术一次读取和处理整个文件。除非文件很大并且会导致内存问题,否则逐行读取文件是没有意义的