我有一个perl代码段
use JSON::XS;
$a = {"john" => "123", "mary" => "456"};
print encode_json($a),"\n";
输出
{"john":"123","mary":"456"}
不知道是否有一个选项可以使encode_json函数(来自JSON :: XS模块)对其进行编码,以使值(123,456)不被双引号包围。即,像
{"john":123,"mary":456}
不幸的是我无法更改$ a中的哈希,因为它是从另一个函数传递给我的。想知道在encode_json()上是否有任何技巧。
谢谢!
答案 0 :(得分:4)
在JSON序列化之前,您可能需要自己预处理数据。
此解决方案使用Data::Leaf::Walker遍历任意结构,将字符串转换为数字。
use JSON;
use Data::Leaf::Walker;
use Scalar::Util qw();
my $a = {"john" => "123",
"mary" => ["456","aa"],
"fred" => "bb",
"nested" => {"Q" => undef, "A" => 42},
};
my $walker = Data::Leaf::Walker->new( $a );
while (my ( $key_path, $value ) = $walker->each ) {
$walker->store($key_path, $value + 0)
if Scalar::Util::looks_like_number $value;
};
print to_json($a);
输出:{"john":123,"nested":{"A":42,"Q":null},"mary":[456,"aa"],"fred":"bb"}
答案 1 :(得分:2)
您不应直接使用JSON::XS
,只有JSON
已加载JSON::XS
(如果有)。
Perl中的标量被标记为是字符串还是数字,在这里您提供字符串。从您的数字中删除引号,它们应显示为不引用,因为JSON
已经自动执行此操作。
如果您正在阅读字符串(例如数据库),那么您可以将字符串强制转换为这样的数字:
{ john => 0+$john, mary => 0+$mary }
更新,这是一个递归替换:
#!/usr/bin/env perl
use JSON;
use Modern::Perl;
use Scalar::Util qw( looks_like_number );
my $structure = {
john => "123",
mary => 456,
deeper => {
lucy => "35zz",
names => [
"john",
"123",
456,
],
},
};
sub make_numbers_recursively {
my ( $data ) = shift;
if ( ref $data eq 'HASH' ) {
# Replace hash values with recurisvely updated values
map { $data->{ $_ } = make_numbers_recursively( $data->{ $_ } ) } keys %$data;
} elsif ( ref $data eq 'ARRAY' ) {
# Replace each array value with recursively processed result
map { $_ = make_numbers_recursively( $_ ) } @$data;
} else {
$data += 0 if looks_like_number( $data );
}
return $data;
}
my $json = JSON->new->pretty;
say $json->encode( $structure );
make_numbers_recursively( $structure );
say $json->encode( $structure );
输出:
{
"mary" : 456,
"deeper" : {
"names" : [
"john",
"123",
456
],
"lucy" : "35zz"
},
"john" : "123"
}
{
"mary" : 456,
"deeper" : {
"names" : [
"john",
123,
456
],
"lucy" : "35zz"
},
"john" : 123
}
请注意,它会就地修改结构,因此如果您需要原始数据,您可能需要首先Clone
或Data::Clone
。