3

我得到了一个文件,(可能)用 Latin-1 (ISO 8859-1) 编码,并且有一些转换和数据挖掘需要用它来完成。输出应该是 UTF-8 格式,我已经尝试了所有我能找到的关于 Perl 中的编码转换的方法,但它们都没有产生任何可用的输出。

我知道这use utf8;从一开始就无济于事。我试过这个Encode包,看起来很有希望:

open FILE, '<', $ARGV[0] or die $!;

my %tmp = ();
my $last_num = 0;

while (<FILE>) {
    $_ = decode('ISO-8859-1', encode('UTF-8', $_));

    chomp;
    next unless length;
    process($_);
}

我尝试了我能想到的任何组合,还加入了binmode(STDOUT, ":utf8");open FILE, '<:encoding(ISO-8859-1)', $ARGV[0] or die $!;等等。结果要么是混乱的变音符号,要么是错误消息,例如\xC3 is not a valid UTF-8 character,甚至是混合文本(一些在 UTF-8 中,一些在 Latin-1 中)。

我想要的只是一种简单的方法来读取 Latin-1 文本文件并通过print. 在 Perl 中是否有任何简单的方法可以做到这一点?

4

3 回答 3

6

请参阅Perl 编码介绍Unicode 食谱

  • 最简单的piconv

    $ piconv -f Latin1 -t UTF-8 < input.file > output.file
    
  • 简单,带有编码层:

    use autodie qw(:all);
    open my $input, '<:encoding(Latin1)', $ARGV[0];
    binmode STDOUT, ':encoding(UTF-8)';
    
  • 适度地,使用手动解码/编码:

    use Encode qw(decode encode);
    use autodie qw(:all);
    
    open my $input, '<:raw', $ARGV[0];
    binmode STDOUT, ':raw';
    while (my $raw = <$input>) {
        my $line = decode 'Latin1', $raw, Encode::FB_CROAK | Encode::LEAVE_SRC;
        my $result = process($line);
        print {STDOUT} encode 'UTF-8', $result, Encode::FB_CROAK | Encode::LEAVE_SRC;
    }
    
于 2012-08-03T09:31:48.580 回答
5

也许作为:

$_ = encode('utf-8', decode('ISO-8859-1', $_));

数据是 gb2312 编码,因此可以将其转换为 utf-8:

#!/usr/bin/env perl

use Encode qw(encode decode);

while (<DATA>) {
    $_ = encode('utf-8', decode('gb2312', $_));
    print;
}

__DATA__
Â׶ذÂÔË»á
于 2012-08-03T08:50:29.703 回答
3
$_ = decode('ISO-8859-1', encode('UTF-8', $_));

这条线有两个问题。首先,您将输入编码为 UTF-8,然后从 ISO-8859-1 解码。这两个操作是错误的。

其次,您几乎肯定不想同时解码和编码。在 Perl 中处理字符编码的黄金法则是遵循这个过程:

  1. 从外部世界获取数据后立即解码。这将获取您的输入字节流并将其转换为 Perl 的字符串内部表示。
  2. 根据您的要求处理数据。
  3. 在将数据发送到外界之前对其进行编码。这采用 Perl 对字符串的内部表示并将其转换为正确编码的字节流,以用于您所需的输出编码。
于 2012-08-03T10:39:46.807 回答