1

我想知道为什么我们的页面上会出现一些德国变音符号。然后我发现最新版本的 JSON(我使用 2.07)确实以不同于 JSON 1.5 的方式转换字符串。

这里的问题是我有一个带有字符串的哈希,例如

use Data::Dumper;
my $test = {
  'fields' => 'überrascht'
};

print Dumper(to_json($test));给我

$VAR1 = "{ \"fields\" : \"\x{fc}berrascht\" } "; 

使用旧模块

$json = JSON->new();
print Dumper ($json->to_json($test));

给了我(正确的结果)

$VAR1 = '{"fields":[{"title":"überrascht"}]}'; 

所以变音符号是使用新的 JSON 2 模块打乱的。

我需要什么才能让它们正确?

更新:使用 Data::Dumper 显示输出可能不好,因为 Dumper 使用自己的编码。好吧,与 Dumper 的结果不同,表明这里对任何事物都进行了不同的处理。正如 Brad 提到的那样描述后端可能会更好:使用 Template-Toolkit 打印 json 字符串,然后将其分配给 javascript 变量以供进一步使用。正确的 javascript 显示类似这样的内容

{
    "title" : "Geändert",
},

使用我得到的新模块

{
    "title" : "Geändert",
},

目标页面位于 8859-1 (latin1) 中。有什么建议么?

4

4 回答 4

5

\x{fc}ü,至少在 Latin-1、Latin-9 等中。此外,üU+00FCUnicode 中的代码点。但是,我们想要 UTF-8(我想)。获取 UTF-8 字符串文字最简单的解决方案是使用这种编码保存您的 Perl 源代码,并将 ause utf8;放在脚本的顶部。

然后,将字符串编码为 JSON 会产生正确的输出:

use strict; use warnings; use utf8;
use Data::Dumper; use JSON;
print Dumper encode_json {fields => "nicht überrascht"};

encode_json假定为 UTF-8 。阅读文档以获取更多信息。

输出:

$VAR1 = '{"fields":"nicht überrascht"}';

(JSON 模块版本:2.53)

于 2013-05-17T16:37:00.543 回答
5
my $json_text = to_json($data);

简称

my $json_text = JSON->new->encode($data);

这将返回一串 Unicode 代码点。U+00FC 确实是“ü”的正确 Unicode 代码点,所以输出是正确的。(作为证明,它的 HTML 源代码实际上是"ü".)

很难说出您的原始输出实际包含什么(因为您显示了非 ASCII 字符),因此很难确定您的问题实际上是什么。

但是在输出字符串之前你必须做的一件事是将它从一串代码点转换为字节,例如,通过使用Encodeencodeencode_utf8.

my $json_cp1252 = encode('cp1252', to_json($data));

my $json_utf8 = encode_utf8(to_json($data));

如果适当的编码是 UTF-8,您还可以使用以下任何一种:

my $json_utf8 = to_json($data, { utf8 => 1 });

my $json_utf8 = encode_json($data);

my $json_utf8 = JSON->new->utf8->encode($data);
于 2013-05-17T17:49:16.507 回答
2

改为使用encode_json。根据手册,它将给定的 Perl 数据结构转换为 UTF-8 编码的二进制字符串。

关于您的更新:如果您真的想在 Latin1 (ISO-8859-1) 中生成 JSON,您可以尝试:

to_json($test, { latin1 => 1 })

或者

JSON->new->latin1->encode($test)

请注意,如果您转储结果,则在这种情况下获取\x{fc}forü是正确的。我猜你问题的根源是你从某个地方接收到 Perl 的 UTF-8 格式的文本。在这种情况下,latin1需要 JSON 模块的选项。

您也可以尝试使用ascii而不是latin1作为最安全的选择。

另一种解决方案可能是为 Template-Toolkit 指定输出编码。我不知道这是否可能。或者,您可以在最后一步将结果编码为 Latin1,然后将其发送给客户端。

于 2013-05-17T15:55:11.767 回答
2

严格来说,Latin-1 编码的 JSON 不是有效的 JSON。JSON 规范允许 UTF-8 、UTF-16 或 UTF-32 编码。

如果您想要符合标准,或者您想要确保您的 JSON 将与您当前的页面和未来基于 UTF-8 的页面兼容,您需要使用JSON->new->utf8->encode($str). 对生成的有效 JSON 保持严格可以在未来为您省去很多麻烦。

如果需要,您可以使用客户端 Javascript 将 UTF-8 JSON 转换为 Latin-1,使用这个技巧

ascii选项还通过使用有效的 JSON unicode 转义转义任何非 ASCII 字符来生成有效的 JSON。但该latin1选项没有,因此应该避免恕我直言。utf8(0)除非您在将数据写入客户端时指定编码,否则也应避免使用该选项:utf8(0)与该选项略有不同utf8,因为它生成 Perl 字符串而不是字节字符串。如果您在没有指定编码的情况下使用字符串进行任何 I/O,Perl 会即时将其翻译回 Latin-1。该utf8选项生成原始 UTF-8 字节,非常适合进行原始 I/O。

于 2013-06-25T20:36:20.683 回答