我在Perl / CGI中有一个应用程序,我收到一个utf8 txt文件并对其内容进行处理。
由于某种原因(我认为Perl将文件分为4096字节缓冲区,只有第一个具有字节顺序标记)Perl在4096字节之后将文件内容解释为Unicode。
如果我在文件中间传播一些短划线(“ - ”)(每个4k块至少有一个),程序会将其识别为utf8,可能是因为Unicode没有短划线。
我从html页面收到txt并将其发送到这样的标量变量:
while(my $l = <$fh>){
$text .= $l;
}
我尝试通过用短划线连接文件的每一行来强制使用utf8:
while(my $l = <$fh>){
$text .= "–".$l;
}
但是我收到了这个错误:
Wide character in print at (eval 12) line 94.
有人有小费吗? 具有 谢谢!
答案 0 :(得分:3)
Perl可以在Unicode代码点上运行,但所有I / O都是用字节完成的。当您将具有高代码点的字符串打印到普通文件句柄时,您会收到“打印中的宽字符”警告。
您应解码所有输入数据,编码所有输出。最好的方法是使用PerlIO层。您可以使用binmode
添加图层。 E.g:
use utf8; # This source file is encoded in UTF-8.
# Else, the literal "–" would be seen as multiple bytes, not one single character.
binmode STDOUT, ":uft8"; # encode all strings (that get printed to STDOUT)
# to the binary UTF-8 representation
print "–\n"; # EN DASH – works.
打开文件时,可以在打开模式下添加PerlIO图层,例如
open my $fh "<:utf8", $filename or die ...;
这会透明地将二进制输入转换为代码点。
不要将包含二进制UTF-8的字节字符串与正确解码的字符串连接起来 - 结果很可能是无效数据。当然,解码所有输入时不会出现此类问题。
Perl缓冲输入的方式不应该影响你的程序;很可能你误诊了。 Perl不通过输入文件上的BOM进行编码检测。
在Web编程环境中,将输出编码为UTF-8是一个不错的选择,但请确保在响应头中设置charset
属性:
Content-Type: text/html; charset=UTF-8
HTML文档应该使用<meta charset="UTF-8">
重复此内容。
答案 1 :(得分:0)
尝试:
use Encode qw(encode);
$text = join '', <$fh>;
$text = encode("utf8", $text);