我有一些文本文件,我试图在 Windows 上使用 Perl 脚本对其进行转换。文本文件在 Notepad+ 中看起来很正常,但我脚本中的所有正则表达式都无法匹配。然后我注意到当我在 NotePad+ 中打开文本文件时,状态栏显示“UCS-2 Little Endia”(原文如此)。我假设这对应于编码 UCS-2LE。所以我在 Perl 中创建了“readFile”和“writeFile”子程序,如下所示:
use PerlIO::encoding;
my $enc = ':encoding(UCS-2LE)';
sub readFile {
my ($fName) = @_;
open my $f, "<$enc", $fName or die "can't read $fName\n";
local $/;
my $txt = <$f>;
close $f;
return $txt;
}
sub writeFile {
my ($fName, $txt) = @_;
open my $f, ">$enc", $fName or die "can't write $fName\n";
print $f $txt;
close $f;
}
my $fName = 'someFile.txt';
my $txt = readFile $fName;
# ... transform $txt using s/// ...
writeFile $fName, $txt;
现在正则表达式匹配(尽管比我预期的要少),但输出包含长串亚洲字符,中间散布着长串正确文本。我的代码错了吗?或者 Notepad+ 的编码有误?我应该如何进行?
最佳答案
好的,我明白了。问题是由“打开”调用的“编码...”参数完成的编码转换与 Perl 在 Windows 上完成的默认 CRLF 转换之间的断开连接引起的。似乎正在发生的事情是 LF 在编码已经完成之后 在输出上被转换为 CRLF,这使下一行的 16 位编码的“奇偶校验”失效。一旦到达下一行,“奇偶校验”就被放回去了。这可以解释“一长串看起来像亚洲人的字符穿插着一长串正确文本”……每一行都被搞砸了。
为了更正它,我在我的“open”调用中取出了编码参数并添加了一个“binmode”调用,如下所示:
open my $f, $fName or die "can't read $fName\n";
binmode $f, ':raw:encoding(UCS-2LE)';
binmode显然有一个有点复杂的“分层”I/O 处理的概念。
我想不通的一件事是如何取回我的 CRLF 翻译。如果我省略 :raw 或添加 :crlf,“奇偶校验”问题就会返回。我也尝试过重新订购,但无法正常工作。
(我将其添加为一个单独的问题:CRLF translation with Unicode in Perl)
关于perl - Perl 中的 Unicode 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3304834/