你在说什么?
$ perl -MJSON -E'
say $JSON::VERSION;
my $json = JSON->new()->objToJson(["\xE4"]);
say sprintf "%v02X", $json;
'
1.15
5B.22.E4.22.5D # Unicode code points for ["ä"]
$ perl -MJSON -E'
say $JSON::VERSION;
my $json = JSON->new()->encode(["\xE4"]);
say sprintf "%v02X", $json;
'
2.59
5B.22.E4.22.5D # Unicode code points for ["ä"]
这两个字符串是相同的!事实上,添加->latin1()
不会改变任何东西,因为 Unicode 代码点 U+00E4 的 iso-8859-1 编码是 E4。
$ perl -MJSON -E'
say $JSON::VERSION;
my $json = JSON->new()->latin1()->encode(["\xE4"]);
say sprintf "%v02X", $json;
'
2.59
5B.22.E4.22.5D # iso-8859-1 encoding of ["ä"]
后两者之间有一个区别:它在标量中的存储方式不同。那应该完全没有区别。如果代码以不同的方式对待它们,则该代码错误地读取了标量中的数据,并且该代码存在错误。
$string_with_umlauts 绝对是 winLatin 中的一个字符串
嗯,这是第一个错误。
JSON 需要解码文本字符串(Unicode 代码点字符串),而不是编码文本。
也就是说,使用 iso-8859-1 编码的字符串和 Unicode 代码点字符串之间恰好没有区别。例如,当使用 iso-8859-1 编码时,“ä”是字节 E4,它是 Unicode 代码点 U+00E4,相同数字的两种不同表示法。
但是,如果字符串是使用 cp1252 编码的,那么字符 €‚ƒ„…†‡ˆ‰Š‹ŒŽ''“”•--∼™š›œžŸ (cp1252 中的字符但 iso 中没有-8859-1)。例如,当使用 cp1252 编码时,“€”是字节 80,但它是 Unicode 代码点 U+20AC。0x80 != 0x20AC。
html 文档位于 iso-8559-1(元标记)中。
然后在某些时候,您必须将输出编码为 iso-8859-1。您可以使用:encoding
层,或使用编码encode
或使用 JSON 的->latin1
指令来完成。使用此最终选项的优点是,它将导致 JSON 在尝试对其进行编码之前转义 iso-8859-1 字符集之外的任何字符。
谁能向我解释为什么?
您有一个代码(一个 XS 模块),它读取标量的底层字符串缓冲区并将其错误地视为字符串的内容。该模块中有一个错误。