PERL | IMAP文件夹编码。 UTF8 - > UTF7 - > UTF8 =失败

时间:2015-03-13 05:31:56

标签: perl encoding utf-8

我需要有关imap文件夹编码的建议。

我是由我的邮件客户端(Thunderbird)使用俄语符号的imap文件夹创建的。

文件夹名称是 - Проверка

文件系统上的文件夹名称是 - user.mylogin。& BB8EQAQ + BDIENQRABDoEMA -

我为convert编写了这段代码(perl v5.10.1)

use strict;
use warnings;
use utf8;
use Encode::IMAPUTF7;

my $folder=$ARGV[1];

binmode(STDOUT,':utf8');

if ($ARGV[0] eq 'to')
    { print Encode::IMAPUTF7::encode('IMAP-UTF-7', $folder) }
    elsif ($ARGV[0] eq 'from')
    { print Encode::IMAPUTF7::decode('IMAP-UTF-7', $folder) }
print "\n";

尝试将文件夹名称转换为俄语

[w@pandora6 tmp]$ ./imapfolder.pl from '&BB8EQAQ+BDIENQRABDoEMA-'
Проверка

一切正常

尝试反向转换

[w@pandora6 tmp]$ ./imapfolder.pl to Проверка
&ANAAnwDRAIAA0AC+ANAAsgDQALUA0QCAANAAugDQALA-

嗯......我期待& BB8EQAQ + BDIENQRABDoEMA -

好的,编码回来

[w@pandora6 tmp]$ ./imapfolder.pl from '&ANAAnwDRAIAA0AC+ANAAsgDQALUA0QCAANAAugDQALA-'
ÐÑовеÑка

WTF?我期待Проверка

出了什么问题?

2 个答案:

答案 0 :(得分:5)

你被其中一个many gotchas of Unicode in Perl抓住了。 use utf8 启用UTF-8语法。这意味着像常量字符串,变量名和函数名这样的东西将是UTF-8。其他一切都不会。具体而言,@ARGV中的字符串不是UTF-8。那些仍然是普通字节。

幸运的是,有一个简单的解决方法。使用utf8::all。这将打开您期望use utf8执行的所有UTF-8功能。

  • 以UTF-8编码@ARGV(当从主包中使用utf8 :: all时)。

  • 默认打开UTF-8编码打开文件句柄(包括STDIN,STDOUT,STDERR)。如果您不想要特定文件句柄的UTF-8,则必须设置binmode $ filehandle。

  • 导入字符,因此\ N {...}序列可用于根据名称编译Unicode字符。

  • readdir现在返回UTF-8字符而不是字节。

  • glob和<> operator现在返回UTF-8字符而不是字节。

您的代码缩减为......

use strict;
use warnings;
use utf8::all;
use Encode::IMAPUTF7;

my $folder=$ARGV[1];

if ($ARGV[0] eq 'to') {
    print Encode::IMAPUTF7::encode('IMAP-UTF-7', $folder)
}
elsif ($ARGV[0] eq 'from') {
    print Encode::IMAPUTF7::decode('IMAP-UTF-7', $folder)
}
print "\n";

答案 1 :(得分:0)

如果您没有安装 utf8::all 而只是想要一个快速的单行,您也可以使用 Perl's -C option 使其在 UTF8 中执行所有操作。

示例:

$ utf7=$(perl -CSA -MEncode::IMAPUTF7 -le 'print Encode::IMAPUTF7::encode("IMAP-UTF-7", shift)' "Проверка")
$ echo "$utf7"
&BB8EQAQ+BDIENQRABDoEMA-

$ perl -CSA -MEncode::IMAPUTF7 -le 'print Encode::IMAPUTF7::decode("IMAP-UTF-7", shift)' "$utf7"
Проверка