Perl输出中的JSON编码

时间:2018-01-12 16:31:38

标签: json perl encoding

上下文
我必须将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,我的代码基于它。主要区别在于,我不确定如何编码文件,而不是简单的字符串。

1 个答案:

答案 0 :(得分:3)

网站配置文件采用UTF-8编码。以下是三种解决方法:

  1. use utf8 pragma放在站点配置文件中。主脚本中的use utf8 pragma不足以将do / require中包含的文件视为UTF-8编码。

  2. 如果这不可行,请在将输入传递给JSON编码器之前解码输入。像

    这样的东西
    open CFG, "<:encoding(utf-8)", $conf;
    do { local $/; eval <CFG> };
    close CFG;
    
  3. 而不是

    do $conf
    
    1. 使用JSON::to_json代替JSON::encode_jsonencode_json期望解码输入(Unicode代码点),输出为UTF-8编码。 to_json的输出未编码,或者更确切地说,它将具有与输入相同的编码,这就是您想要的。
    2. 无需将最终输出编码为UTF-8。使用三种解决方法中的任何一种都将产生UTF-8编码输出。