node.js -有没有合适的方法来解析大数字的JSON?(long,bigint,int 64)

ergxz8rk  于 2023-03-29  发布在  Node.js
关注(0)|答案(5)|浏览(124)

当我解析这一小段JSON时:

{ "value" : 9223372036854775807 }

这是我得到的:

{ hello: 9223372036854776000 }

有没有什么方法可以正确地解析它?

63lcw9qa

63lcw9qa1#

内置的JSON. parse不能。你需要手动解析它,并将值视为字符串(如果你想用它们做算术,有bignumber.js)你可以使用道格拉斯Crockford JSON.js库作为你的解析器的基础。
EDIT 2(原始答案7年后)- * 可能很快就可以使用标准JSON API解决这个问题。看看这个TC 39提案,将访问源字符串添加到reviver函数-https://github.com/tc39/proposal-json-parse-with-source *
编辑1:我为你创建了一个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}
u4vypkhs

u4vypkhs2#

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

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
   })
3gtaxfhh

3gtaxfhh3#

你可以试试我的库,它可以解决这个问题:https://www.npmjs.com/package/json-with-bigint
示例:

import { JSONParse, JSONStringify } from 'json-with-bigint';

const userData = {
  someBigNumber: 9007199254740991n
};

localStorage.setItem('userData', JSONStringify(userData));

const restoredUserData = JSONParse(localStorage.getItem('userData'));

它支持往返操作,因此您可以安全地stringify和解析BigInt值,而不会丢失任何内容。
它与原生JSON.parse/JSON.stringify的工作原理相同,除了BigInt之外。

xbp102n0

xbp102n04#

正则表达式很难在所有情况下都正确。
这是我的尝试,但我给你的只是一些额外的测试用例,而不是解决方案。可能你会想替换一个非常特定的属性,和一个更通用的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);
bttbmeg0

bttbmeg05#

你可以用这段代码把大数字转换成字符串,然后再用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);

相关问题