UTF-8编码的JSON文件,尝试使用JSON模块解析 - 宽字符

5

我有一个相当简单的Perl脚本:

use JSON;

use open qw/ :std :encoding(utf8) /;

#my $ref = JSON::decode_json($json_contents);

my $path = "/home/chambres/web/x.org/public_html/cgi-bin/links/admin/booking_import/import/file.json";

my $json_contents = slurp_utf8_file($path);

my $ref =  JSON->new->utf8->decode($json_contents);

sub slurp_utf8_file {

  my @back;
  #open my $in,  '<:encoding(UTF-8)',  $_[0]  or die $!;
  open my $in,  "<$_[0]" or die $!;
    while (<$in>) {
      push @back, $_
    }
  close ($in);

  return join("", @back);
}

文件在Notepad++中以UTF-8编码:

enter image description here

...然而当我运行我的脚本时,我得到:

perl test.cgi
Wide character in subroutine entry at test.cgi line 11.

第11行是:
my $ref =  JSON->new->utf8->decode($json_contents);

我很困惑自己做错了什么。也许我只需要休息一下!非常感谢任何建议!


2
你难道不是试图进行双重UTF-8解码吗?你已经在slurp中解码了UTF-8,为什么还需要在JSON对象上使用->utf8呢? - Stefan Becker
1个回答

5

您正在尝试对UTF-8进行双重解码:

#!/usr/bin/perl
use strict;
use warnings;

use JSON;
use Data::Dumper;

open(my $fh,  '<:encoding(UTF-8)', $ARGV[0]) or die $!;
my @lines = <$fh>;
close($fh) or die $!;

# Wide character in subroutine entry at dummy.pl line 14.
my $ref = JSON->new->utf8->decode(join('', @lines));

# OK, no warning.
my $ref = JSON->new->decode(join('', @lines));

print Dumper($ref);

exit 0;

测试运行

$ cat dummy.json
{
   "path": "ä⁈"
}

# with ->utf8
$ perl dummy.pl dummy.json
Wide character in subroutine entry at dummy.pl line 14.

# without ->utf8
$ perl dummy.pl dummy.json
$VAR1 = {
          'path' => "\x{e4}\x{2048}"
        };

有时候你只需要多一双眼睛来审视它!我想这是因为尝试使用File::Slurp::read_file,但显然它不支持utf8 - 所以我转而自己读取文件,但猜测我也没有将那部分删除。感谢您挽救了我的理智 :) - Andrew Newby
3
建议使用File::Slurper而不是先前提到的模块,因为它具有更加简单明了的函数。您可以使用read_binary函数按原样读取字节,然后使用标准的UTF-8解码JSON解码器。 - Grinnz
@Grinnz 谢谢你的建议。我会记住下一个项目时尝试使用它 :) (目前,我正在使用的方法已经能够满足需求,所以没有必要包含整个额外模块 :)) - Andrew Newby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接