在 Perl 中读取 UTF-8 并输出为 ISO-8859-1
Read UTF-8 in Perl and output as ISO-8859-1
我必须读取编码为 UTF-8 的 Perl 文本文件,它工作正常。我的输出文件 OUT_2 必须编码为 ISO-8859-1(又名 "Latin1")。我尝试了这段代码(以及更多代码),但我的输出文件 OUT_2 始终写为 UTF-8。有实现它的想法吗?
use strict;
use Encode::Encoder;
open IN, "c:/Temp/Input.txt"; # this file is UTF-8
open OUT_1, ">", "c:/Temp/out_1.txt";
# encoding of OUT_1 does not matter because it contains only ASCII
open OUT_2, ">:encoding(latin1)", "c:/Temp/out_2.txt";
my $line = 1;
while ( <IN> ) {
chomp;
print OUT_1 "Write line $line\n";
print OUT_2 "$_ and some stuff\n";
$line++;
}
close IN;
close OUT_1;
close OUT_2;
这个提议也不行:
my $data = "$_ and some stuff\n";
Encode::encode("latin1", Encode::decode("UTF-8", $data));
print OUT_2 $data;
我认为您正在寻找 Encode::encode($encoding_out, Encode::decode($encoding_in, $data));
,其中 $encoding_in
和 $encoding_out
分别是 UTF-8 和 Latin1 (iso-8859-1)。
如果 UTF-8 中有不可打印的字符,则无损转换将是不可能的,因为 UTF-8 中可能的字符集大于 Latin-1 中可能的字符集。任何不翻译的字符都将替换为“?”。
这似乎工作正常(参见 Perl 的 open function; there is no need to explicitly transform the Perl string on the octet level using encode/decode) (further afield, possibly see the description of the open pragma and the binmode 函数的描述):
#!/usr/bin/perl
use strict;
use warnings;
open my $in, '<:encoding(UTF-8)', 'input-file-name' or die $!;
open my $out, '>:encoding(latin1)', 'output-file-name' or die $!;
while (<$in>) {
print $out $_;
}
与您的代码唯一实质性区别是我明确地将传入数据从 UTF8 字节解码为字符。
您正在做什么来查明您的输入和输出文件的编码是什么?我用过 file
.
$ file input-file-name output-file-name
input-file-name: UTF-8 Unicode text
output-file-name: ISO-8859 text
还有od -ch
:
$ od -ch input-file-name
0000000 a a a 302 243 302 243 302 243 z z z \n
6161 c261 c2a3 c2a3 7aa3 7a7a 000a
0000015
$ od -ch output-file-name
0000000 a a a 243 243 243 z z z \n
6161 a361 a3a3 7a7a 0a7a
0000012
(我的文件包含 "aaa£££zzz"。)
我必须读取编码为 UTF-8 的 Perl 文本文件,它工作正常。我的输出文件 OUT_2 必须编码为 ISO-8859-1(又名 "Latin1")。我尝试了这段代码(以及更多代码),但我的输出文件 OUT_2 始终写为 UTF-8。有实现它的想法吗?
use strict;
use Encode::Encoder;
open IN, "c:/Temp/Input.txt"; # this file is UTF-8
open OUT_1, ">", "c:/Temp/out_1.txt";
# encoding of OUT_1 does not matter because it contains only ASCII
open OUT_2, ">:encoding(latin1)", "c:/Temp/out_2.txt";
my $line = 1;
while ( <IN> ) {
chomp;
print OUT_1 "Write line $line\n";
print OUT_2 "$_ and some stuff\n";
$line++;
}
close IN;
close OUT_1;
close OUT_2;
这个提议也不行:
my $data = "$_ and some stuff\n";
Encode::encode("latin1", Encode::decode("UTF-8", $data));
print OUT_2 $data;
我认为您正在寻找 Encode::encode($encoding_out, Encode::decode($encoding_in, $data));
,其中 $encoding_in
和 $encoding_out
分别是 UTF-8 和 Latin1 (iso-8859-1)。
如果 UTF-8 中有不可打印的字符,则无损转换将是不可能的,因为 UTF-8 中可能的字符集大于 Latin-1 中可能的字符集。任何不翻译的字符都将替换为“?”。
这似乎工作正常(参见 Perl 的 open function; there is no need to explicitly transform the Perl string on the octet level using encode/decode) (further afield, possibly see the description of the open pragma and the binmode 函数的描述):
#!/usr/bin/perl
use strict;
use warnings;
open my $in, '<:encoding(UTF-8)', 'input-file-name' or die $!;
open my $out, '>:encoding(latin1)', 'output-file-name' or die $!;
while (<$in>) {
print $out $_;
}
与您的代码唯一实质性区别是我明确地将传入数据从 UTF8 字节解码为字符。
您正在做什么来查明您的输入和输出文件的编码是什么?我用过 file
.
$ file input-file-name output-file-name
input-file-name: UTF-8 Unicode text
output-file-name: ISO-8859 text
还有od -ch
:
$ od -ch input-file-name
0000000 a a a 302 243 302 243 302 243 z z z \n
6161 c261 c2a3 c2a3 7aa3 7a7a 000a
0000015
$ od -ch output-file-name
0000000 a a a 243 243 243 z z z \n
6161 a361 a3a3 7a7a 0a7a
0000012
(我的文件包含 "aaa£££zzz"。)