Perl脚本的奇怪行为(附加斜杠)

时间:2014-01-17 11:58:45

标签: json perl gettext po

对于我的项目的本地化,我使用gettext。我使用 po2json 脚本将我的翻译文件从 .po 格式转换为 .json 格式。一切都运行良好,除了一件事 - 如果我要转换的行包含控制字符,在.json文件中这些字符被转义,最终字符串与代码不匹配(因此这个短语没有翻译)。 我试图理解脚本,但我不知道Perl,我不明白额外斜线的来源。

这是原始.po文件的代码和部分,并转换为.json:

剧本:

my $pos = Locale::PO->load_file_asarray($src) or die "Can't parse po file [$src].";

foreach my $po (@$pos)
{
    my $qmsgid1 = $po->msgid;
    my $msgid1 = $po->dequote( $qmsgid1 );


    my $qmsgctxt = $po->msgctxt;
    my $msgctxt = $po->dequote($qmsgctxt) if $qmsgctxt;

    # build the new msgid key
    my $msg_ctxt_id = defined($msgctxt) ? join($gettext_context_glue, ($msgctxt, $msgid1)) : $msgid1;

    # build translation side
    my @trans;

    # msgid plural side
    my $qmsgid_plural = $po->msgid_plural;
    my $msgid2 = $po->dequote( $qmsgid_plural ) if $qmsgid_plural;
    push(@trans, $msgid2);

     # translated string
     # this shows up different if we're plural
     if (defined($msgid2) && length($msgid2))
     {
        my $plurals = $po->msgstr_n;
        for (my $i=0; $i<$plural_form_count; $i++)
        {
            my $qstr = ref($plurals) ? $$plurals{$i} : undef;
            my $str  = $po->dequote( $qstr ) if $qstr;
            push(@trans, $str);
        }

    # singular
    } else {
        my $qmsgstr = $po->msgstr;
        my $msgstr = $po->dequote( $qmsgstr ) if $qmsgstr;
        push(@trans, $msgstr);
    }

    $$json{$msg_ctxt_id} = \@trans;
}


my $jsonobj = new JSON;
my $basename = basename($src);
$basename =~ s/\.pot?$//;
if ($pretty)
{
    print $jsonobj->pretty->encode( { $basename => $json });
} else {
    print $jsonobj->encode( { $basename => $json } );
}

源.po文件示例:

#: some/path/to/file1.php:37
msgid "Original string without command character"
msgstr "Translated string without command character"

#: some/path/to/file2.php:73
msgid "Original string with\ncommand character"
msgstr "Translated string with\ncommand character"

转换后的.json文件:

{"Original string without command character":[null,"Original string without command character"],"Translated string with\\ncommand character":[null,"Translated string with\\ncommand character"]}

我将不胜感激任何建议或提示!

我很抱歉,我真的不熟悉Perl ......

1 个答案:

答案 0 :(得分:2)

如果您有换行符,则会获得"\n"

>perl -MJSON -E"say encode_json [ chr(0x0A) ]"
["\n"]

您没有换行符。您有\后跟n

>perl -MJSON -E"say encode_json [ chr(0x5C).chr(0x6E) ]"
["\\n"]

必须对\进行转义,否则上面的两个字符串都会返回相同的内容,这意味着其中一个字符串会被解码错误。

您可以通过查看解码后是否取回原始字符串来验证编码是否正确。

>perl -MJSON -E"print encode_json [ chr(0x0A) ]" |
    perl -MJSON -nE"say sprintf '%v02X', decode_json($_)->[0]"
0A

>perl -MJSON -E"print encode_json [ chr(0x5C).chr(0x6E) ]" |
    perl -MJSON -nE"say sprintf '%v02X', decode_json($_)->[0]"
5C.6E