node.js - 是否有任何正确的方法来解析大量的 JSON? (long, bigint, int64)

问题描述 投票:0回答:4

当我解析这一小段 JSON 时:

{ "value" : 9223372036854775807 }

这就是我得到的:

{ hello: 9223372036854776000 } 

有没有办法正确解析它?

node.js long-integer bigint int64
4个回答
61
投票

不适用于内置的 JSON.parse。您需要手动解析它并将值视为字符串(如果您想对它们进行算术运算,可以使用 bignumber.js)您可以使用 Douglas Crockford JSON.js 库作为解析器的基础。

EDIT2(原始答案后 7 年)- 可能很快就可以使用标准 JSON api 解决这个问题。看看这个 TC39 提案,将对源字符串的访问添加到 reviver 函数 - https://github.com/tc39/proposal-json-parse-with-source

EDIT1:我为你创建了一个package:)

var JSONbig = require('json-bigint');

var json = '{ "value" : 9223372036854775807, "v2": 123 }';
console.log('Input:', json);
console.log('');

console.log('node.js bult-in JSON:')
var r = JSON.parse(json);
console.log('JSON.parse(input).value : ', r.value.toString());
console.log('JSON.stringify(JSON.parse(input)):', JSON.stringify(r));

console.log('\n\nbig number JSON:');
var r1 = JSONbig.parse(json);
console.log('JSON.parse(input).value : ', r1.value.toString());
console.log('JSON.stringify(JSON.parse(input)):', JSONbig.stringify(r1));

输出:

Input: { "value" : 9223372036854775807, "v2": 123 }

node.js bult-in JSON:
JSON.parse(input).value :  9223372036854776000
JSON.stringify(JSON.parse(input)): {"value":9223372036854776000,"v2":123}


big number JSON:
JSON.parse(input).value :  9223372036854775807
JSON.stringify(JSON.parse(input)): {"value":9223372036854775807,"v2":123}

2
投票

在搜索更干净的东西后——只找到像 jsonbigint 这样的库,我就写了我自己的解决方案。不是最好的,但它解决了我的问题。对于那些使用 Axios 的人,你可以在 transformResponse 回调中使用它(这是我最初的问题——Axios 解析 JSON 并且所有 bigInts 都出错了),

const jsonStr = `{"myBigInt":6028792033986383748, "someStr":"hello guys", "someNumber":123}`
const result = JSON.parse(jsonStr, (key, value) => {
 if (typeof value === 'number' && !Number.isSafeInteger(value)) {
     let strBig = jsonStr.match(new RegExp(`(?:"${key}":)(.*?)(?:,)`))[1] // get the original value using regex expression 
     return strBig //should be BigInt(strBig) - BigInt function is not working in this snippet
 }
 return value
   })
   console.log({
   "original": JSON.parse(jsonStr),
   "handled": result
   })


0
投票

正则表达式很难适用于所有情况。

这是我的尝试,但我给你的只是一些额外的测试用例,而不是解决方案。您可能想要替换一个非常具体的属性和一个更通用的 JSON 解析器(处理分离属性,但将数字属性保留为字符串),然后您可以将该特定的长数字用引号引起来,然后再继续解析为JavaScript 对象。

let str = '{ "value" : -9223372036854775807, "value1" : "100", "strWNum": "Hi world: 42 is the answer", "arrayOfStrWNum": [":42, again.", "SOIs#1"], "arrayOfNum": [100,100,-9223372036854775807, 100, 42, 0, -1, 0.003] }'
let data = JSON.parse(str.replace(/([:][\s]*)(-?\d{1,90})([\s]*[\r\n,\}])/g, '$1"$2"$3'));
console.log(BigInt(data.value).toString());
console.log(data);


-1
投票

您可以使用此代码将大数字更改为字符串,然后使用 BigInt(data.value)

let str = '{ "value" : -9223372036854775807, "value1" : "100" }'
let data = JSON.parse(str.replace(/([^"^\d])(-?\d{1,90})([^"^\d])/g, '$1"$2"$3'));
console.log(BigInt(data.value).toString());
console.log(data);

© www.soinside.com 2019 - 2024. All rights reserved.