上下文
我必须将Perl脚本迁移到Python中。问题在于此Perl脚本使用的配置文件实际上是有效的Perl代码。我的Python版本使用.yaml文件作为配置。
因此,我基本上不得不在Perl和yaml之间编写一个转换器。考虑到这一点,根据我的发现,Perl不能很好地与Yaml一起使用,但是有些库允许将Perl哈希转储到JSON中,并且Python与JSON一起使用 - 几乎是原生的,我使用这种格式作为中间件:Perl - &gt ; JSON - > YAML。第一次转换是在Perl代码中完成的,第二次转换是在Python代码中完成的(它还对数据进行了一些修改)。
使用@simbabque提到的库,我可以原生输出YAML,之后我必须修改和播放。据我所知,Perl几乎没有,我更喜欢在Python中这样做。
问题:
源配置文件如下所示:
$sites = {
"0100101001" => {
mail => 1,
from => 'mail@mail.com',
to => 'mail@mail.com',
subject => 'á é í ó ú',
msg => 'á é í ó ú',
ftp => 0,
sftp => 0,
},
"22222222" => {
[...]
还有更多。
我的解析"代码如下:
use strict;
use warnings;
# use JSON;
use YAML;
use utf8;
use Encode;
use Getopt::Long;
my $conf;
GetOptions('conf=s' => \$conf) or die;
our (
$sites
);
do $conf;
# my $json = encode_json($sites);
my $yaml = Dump($sites);
binmode(STDOUT, ':encoding(utf8)');
# print($json);
print($yaml);
没有什么不寻常的。我只需要Perl数据的 JSON YAML版本。事实上,它主要起作用。我的问题在于编码。
上述代码的输出是:
[...snip...]
mail: 1
msg: á é à ó ú
sftp: 0
subject: á é à ó ú
[...snip...]
编码进入了地狱和回归。据我所知,UTF-8是默认的,以防万一,我用binmode强制它,但无济于事。
我在这里缺少什么?任何解决方法?
注意:我以为我可能是我的shell,但locale
输出了这个:
❯ locale
LANG=
LC_COLLATE="C"
LC_CTYPE="UTF-8"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL=
这似乎没问题。
注意2:我对Perl几乎一无所知,并且我不打算成为它的专家,所以任何增强/提示都非常受欢迎。
注3:我读过this answer,我的代码基于它。主要区别在于,我不确定如何编码文件,而不是简单的字符串。
答案 0 :(得分:3)
网站配置文件采用UTF-8编码。以下是三种解决方法:
将use utf8
pragma放在站点配置文件中。主脚本中的use utf8
pragma不足以将do
/ require
中包含的文件视为UTF-8编码。
如果这不可行,请在将输入传递给JSON编码器之前解码输入。像
这样的东西open CFG, "<:encoding(utf-8)", $conf;
do { local $/; eval <CFG> };
close CFG;
而不是
do $conf
JSON::to_json
代替JSON::encode_json
。 encode_json
期望解码输入(Unicode代码点),输出为UTF-8编码。 to_json
的输出未编码,或者更确切地说,它将具有与输入相同的编码,这就是您想要的。无需将最终输出编码为UTF-8。使用三种解决方法中的任何一种都将产生UTF-8编码输出。