编码json时在数值周围不加引号

编码json时在数值周围不加引号,json,perl,Json,Perl,我有一个perl代码片段 use JSON::XS; $a = {"john" => "123", "mary" => "456"}; print encode_json($a),"\n"; 输出是 {"john":"123","mary":"456"} 想知道是否有一个选项可以使encode_json函数(来自json::XS模块)对其进行编码,从而使值(123456)不被双引号包围。i、 比如 {"john":123,"mary":456} 不幸的是,我无法更改$a中的哈希

我有一个perl代码片段

use JSON::XS;
$a = {"john" => "123", "mary" => "456"};
print encode_json($a),"\n";
输出是

{"john":"123","mary":"456"}
想知道是否有一个选项可以使encode_json函数(来自json::XS模块)对其进行编码,从而使值(123456)不被双引号包围。i、 比如

{"john":123,"mary":456}
不幸的是,我无法更改$a中的哈希,因为它是从另一个函数传递给我的。想知道encode_json()上是否有任何技巧


谢谢

您不应该直接使用
JSON::XS
,只要
JSON
已经加载
JSON::XS
(如果可用)

Perl中的标量被标记为字符串还是数字,这里您提供的是字符串。删除数字中的引号,它们将显示为未加引号的
JSON
已经自动完成了

如果您正在读取字符串(例如从数据库中),则可以将字符串强制为如下所示的数字:

{john=>0+$john,mary=>0+$mary}

更新,这里有一个递归替换:

#/usr/bin/env perl
使用JSON;
使用Modern::Perl;
使用Scalar::Util qw(看起来像数字);
我的$structure={
约翰=>“123”,
玛丽=>456,
更深=>{
露西=>“35zz”,
名称=>[
“约翰”,
"123",
456,
],
},
};
子生成数{
我的($data)=班次;
if(参考$data eq‘哈希’){
#用循环更新的值替换哈希值
map{$data->{$}=make_numbers\u递归($data->{$}})keys%$data;
}elsif(参考$data eq‘ARRAY’){
#用递归处理的结果替换每个数组值
映射{$\=make_numbers_递归($\}@$数据;
}否则{
$data+=0,如果看起来像编号($data);
}
返回$data;
}
我的$json=json->new->pretty;
说$json->encode($structure);
递归地生成数字($structure);
说$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
}

请注意,它会修改原有的结构,因此,如果您需要任何原始数据,您可能需要
克隆
数据::克隆
它。

在JSON序列化之前,您可能需要自己预处理数据

此解决方案用于遍历任意结构,将字符串转换为数字

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”}

感谢您的快速回复。散列$a有数百个字段(都有数值),使用添加“0”的技巧使其成为数值会影响性能。更喜欢在encode_json()中执行,这是用C实现的。另外一点,如果我使用“json”而不是“json::XS”模块,脚本将是相同的(除了模块名称的更改),性能会有很大的差异。使用“json”模块在$a上编码_json()100000次需要2.00秒,使用“json::XS”需要0.048秒。数据结构有多扁平?如果它是平面的,您可以轻松地在适当的位置修改它们,如果它不是平面的,则需要做更多的工作,但仍然是可行的。模块中没有任何东西允许您动态执行,因此必须在Perl端执行。请注意/^\d+$/,这也可以匹配unicode数字。这可能是不可取的。此外,它也不能捕获所有有效的数字,如浮点数和负数等。@codingFun:你为什么说“使用添加“0”的技巧使其成为数字会影响性能”?我怀疑你是否能测量出这种差异。请不要因为猜测而否定可行的解决方案。