我有一个使用Spreadsheet :: XLSX模块读取xlsx文件的脚本,使用字符串插值准备一条消息:
$message = "this is my message in my language $xlscontents";
然后使用Email :: Sender :: Simple通过电子邮件发送。 Pragma'使用utf8'已设置。
问题是,虽然正确显示了字符串文字(使用国家字符),但变量$ xlscontents不是:尽管变量中保存的字符串已经以UTF-8编码,但每个UTF字符都被视为如果它是一系列单独的8位字符,它们将被单独重新编码。最终的结果当然是垃圾。至少这是我看到它的方式,因为只有被读入$ xlscontents变量的片段被破坏了;我语言中的文字正确显示。我还用十六进制查看器查看了电子邮件消息,它看起来就是这样。
我的理论是,尽管Perl知道字符串文字是UTF编码的,但它似乎相信该变量是8位ASCII(或另一个8位代码),并且在插值期间尝试对其进行编码。我的问题: *我怎么能验证这个理论?有没有办法逐字节地筛选Perl变量内容? *我如何告知Perl该变量已经是UTF编码的,不需要重新编码?
该脚本仅使用屏幕消息传递一直运行良好,但当我开始播放电子邮件时,我发现所有文本都被破坏了。所以我给了utf支持,从那时起文字显示正确,但变量内容不是,显然我仍然缺少一些东西。
答案 0 :(得分:0)
如果有人谷歌搜索这个问题: 因为Perl有自己的内部字符串表示,为了确保正确处理字符串,你需要在它们从工作表或命令行中读取后对它们进行解码:
$value = Encode::decode( "UTF8", ($sheet -> {Cells} [0] [0]) -> {Val} );
$value = ($sheet -> {Cells} [0] [0]) -> {Val} ); utf8::decode($value);
如果直接读取文件,也可以在开头指定转换。有许多与Unicode相关的警告,因此最好先阅读https://perldoc.perl.org/perlunicode.html。
答案 1 :(得分:-1)
您可以使用Devel :: Peek查看字符串是如何"编码"。
use Devel::Peek;
Dump( $xlscontents );
将字符串的内容和内部表示打印到STDERR。如果它包含正确的编码ut8,但没有设置UTF8标志,则可以使用
Encode::_utf8_on($xlscontents)
解决这个问题。请先阅读http://perldoc.perl.org/Encode.html#Messing-with-Perl%27s-Internals。