【问题标题】:How to convert \u0421 into letter "C"?如何将\u0421转换为字母“C”?
【发布时间】:2020-01-03 19:09:35
【问题描述】:

我对服务器进行了 post 查询并获得了 json。它包含错误的符号:而不是“正确”,我得到了“\u0421orrect”。如何编码此文本?

一个 parse_json 函数像“РЎorrect”一样执行它;

我发现了

$a = "\x{0421}orrect";
$a= encode("utf-8",  $a);

返回“РЎorrect”,并且

$a = "\x{0421}orrect";
$a= encode("cp1251",  $a);

返回“正确”

所以我决定将 \u 更改为 \x,然后使用 cp1251。

\u to \x

我写道:

Encode::Escape::enmode 'unicode-escape', 'perl';
Encode::Escape::demode 'unicode-escape', 'python';       
$content= encode 'unicode-escape', decode 'unicode-escape', $content;

得到了\x{0421}正确的。

然后我尝试了:

$content = encode( 'cp1251', $content );

而且……没有任何改变!我还有\x{0421}更正...

我注意到一些有趣的事情:

$a = "\x{0421}orrect";
$a= encode("cp1251",  $a);

返回“正确”

但是

$a = '\x{0421}orrect';
$a= encode("cp1251",  $a);

仍然返回“\x{0421}orrect”。

也许这是一把钥匙,但我不知道我能用它做什么。

我已经尝试过编码和解码,Encode::from_to,JSON::XS 和 utf8。

【问题讨论】:

  • "got json": Content-Type 响应头值是什么?
  • @mob 我看过这个页面,但它并没有帮助我让我的代码工作)
  • @TomBlodget 'application/json; charset=utf-8'
  • 您似乎对调试输出感到困惑。原始响应处理工作或可以像@ikegami 的答案一样工作

标签: json perl utf-8 encode


【解决方案1】:

您多次提到转义,但您想做相反的事情(unescape)。

decode_json/from_json 将正确返回“Сorrect”(其中“C”是西里尔大写字母 ES)。

use JSON::XS qw( decode_json );

my $json_utf8 = '{"value":"\u0421orrect"}';
my $data = decode_json($json_utf8);

不过,您确实需要对输出进行编码。例如,如果你有基于 Cyrillic 的 Windows 系统,并且你想创建一个原生文件,你可以使用

open(my $fh, '>:encoding(cp1251)', $qfn)
   or die("Can't create \"$qfn\": $!\n");

say $fh $data->{value};

如果您想对编码进行硬编码,或者如果您对输出到 STDOUT 和 STDERR 的编码也感兴趣,请查看this

【讨论】:

  • decode_json/from_json 将正确返回“Сorrect” 不,我仍然得到РЎorrect
  • 我执行了use JSON::XS qw( decode_json ); my $json_utf8 = '{"value":"\u0421orrect"}'; my $data = decode_json($json_utf8); open(my $fh, '>:encoding(cp1251)', "test.txt") or die("Can't create \"test.txt\": $!\n"); print $fh $data->{'value'}; say $data->{'value'}; 并得到了РЎorrect和令人惊讶的空文本文件......
  • 它会将错误的内容打印到 STDOUT,因为您没有对发送到 STDOUT 的内容进行编码。我的回答已经涵盖了这一点。但是,它并没有像您声称的那样创建一个空文件。它正确地将使用 cp1251 编码的Сorrect 写入文件。
  • 好吧,如果你得到错误Can't call method "say" on unblessed reference,那是因为你没有添加use feature qw( say );。当然,您应该始终使用use strict; use warnings;,尽管这在这里不应该有效果。
  • 对不起,这是我的错误,我在文件中输入了正确,我不知道它是什么,为什么我没有看到这个词。我使用use PerlIO::encoding; 对 STDUT 进行编码,但得到了 \x{0421}orrect... 任何方式在文件中都正确 - 这是一个很大的进步)但是,我正在编写 API,所以我应该处理这个 json 并以正确的形式返回它...我怎样才能让这个词成为我的代码中的Correct
【解决方案2】:

如果您已经意识到这一点,我们深表歉意 - 我只是认为值得指出,所以我们都在同一个页面上。

因此,根据您使用的字体,这两个字符很可能看起来相同。

您问“如何编码此文本?”但是您没有解释您的意思或为什么要“编码”它。没有将“С”(\x{0421})转换为“C”(\x{0043})的编码 - 它们是来自两个不同字母的两个不同字符。

所以问题是,您要实现什么目标?您是否尝试检查从服务器返回的字符串是否匹配"Correct"?如果是这样,那根本行不通,因为服务器正在返回字符串"Сorrect"。它们可能看起来相同,但它们是两个不同的字符串。

整个情况可能是服务器代码中的错误,它应该返回"Correct"。如果是这种情况并且您不能依赖服务器可靠地返回"Correct",则一种解决方法是使用character replacement,在检查其内容之前“规范化”字符串。例如:

use JSON::XS qw( decode_json );

my $response = <<EOF;
{
    "status": "\u0421orrect"
}
EOF

my $data = decode_json($response);

my $status = $data->{status};
$status =~ tr/\x{0421}/C/;

if($status eq "Correct") {
    say "The status is correct";
}
else {
    say "The status is not correct";
}

如果服务器代码被修复为返回"Correct",则此代码现在可以使用。

【讨论】:

    猜你喜欢
    • 2015-11-24
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 2015-08-07
    • 1970-01-01
    • 2012-03-31
    • 2013-02-08
    • 2013-09-03
    相关资源
    最近更新 更多