脚本很好地提取和打印UTF-8单词,但将JSON打印为垃圾

时间:2015-04-02 09:30:39

标签: json perl utf-8

我在Mac OS Mavericks(perl 5.16.2)和Yosemite以及Windows 7(草莓-perl-5.20.1.1-64bit-portable)上尝试过我的脚本。

它应该读取UTF-8数据(俄语文本)并将其放入数据结构中 - 最后将数据结构打印为JSON字符串(输出将用于在iOS文字游戏中提供Core Data)。

第一部分工作(提取单词并打印它们 - 验证)效果很好,但最后一部分不是:生成的JSON字符串包含垃圾:

screenshot

有人请知道,如何修复我的简单测试脚本?

#!/usr/bin/perl -w

use strict;
use warnings;
use utf8;
use JSON;

binmode(STDOUT, ':utf8');

my $root = { words => [] };

while (<DATA>) {
        chomp;
        utf8::decode($_);
        my @a = split /\s*[:,]\s*/;

        my $words = [];
        for my $word (@a[1 .. $#a]) {
                print "WORD: $word\n";
                #push @$words, utf8::encode($word);
                push @$words, $word;
        }

        push @{$root->{words}}, $words;
}

print to_json($root, {utf8 => 1, pretty => 1});

__DATA__
Голова: небо, язык, мозг, глотка, надгортанник, пищевод, горло, гортань
Сумки: портмоне, кошелек, портфель, рюкзак, лямка, застежка

2 个答案:

答案 0 :(得分:3)

输出看起来“错误”,但没关系:它是编码的。要正确查看,请设置

binmode STDOUT, ':raw';

在打印JSON之前。

您可以使用encode_json

简化脚本
#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use JSON;

binmode(STDIN, ":utf8");
binmode(STDOUT, ":utf8");

my $root;

while (<DATA>) {
        chomp;
        my @words = split /\s*[:,]\s*/;
        push @{ $root->{words} }, [];

        for my $word (@words[1 .. $#words]) {
                print "WORD: $word\n";
                push @{ $root->{words}[-1] }, $word;
        }
}

my $json = encode_json($root);
binmode STDOUT, ':raw';
print $json;

答案 1 :(得分:3)

你是双重编码。您使用from_jsonutf8 => 1)进行编码,然后在输出到STDOUTbinmode(STDOUT, ':utf8');)时再次进行编码。

解决方案尚不清楚,因为目前尚不清楚您要实现的目标。如果您真的要将非JSON和JSON输出到STDOUT,请不要让from_json进行编码。