如何在Node.js中解析包含"NaN"的JSON字符串

pro*_*ype 17 json gson node.js

有一个node.js应用程序正在接收包含文字NaN的JSON数据字符串,例如

 "[1, 2, 3, NaN, 5, 6]"
Run Code Online (Sandbox Code Playgroud)

JSON.parse(...)在Node.js 崩溃了.如果我可以进入一个物体,我想解析它.

我知道NaN这不是JSON规范的一部分.大多数SO链接(在json中发送NaN)建议修复输出.

在这里,尽管数据是在我无法控制的服务器中生成的,但它是由商业Java库在哪里我可以看到源代码.它由Google的Gson库生成:

private Gson gson = (new GsonBuilder().serializeSpecialFloatingPointValues().create()); 
... 
gson.toJson(data[i], Vector.class, jsonOut)
Run Code Online (Sandbox Code Playgroud)

所以这似乎是一个合法的来源.根据Gson API Javadoc,它说我应该能够解析它:

JSON规范的2.4节不允许使用特殊的双精度值(NaN,Infinity,-Infinity).但是,Javascript规范(参见4.3.20,4.3.22,4.3.23节)允许这些值作为有效的Javascript值.而且,大多数JavaScript引擎都会在JSON中接受这些特殊值而不会出现问题.因此,在实际层面上,即使JSON规范不允许将这些值作为有效的JSON接受也是有意义的.

尽管如此,Node.js和Chrome都失败了: JSON.parse('[1,2,3,NaN,"5"]')

在JSON.parse()中是否有要设置的标志?或者NaN作为文字接受的替代解析器?

我已经谷歌搜索了一段时间,但似乎无法找到关于这个问题的文档.

PHP:如何将无穷大或NaN数编码为JSON?

T.J*_*der 33

有一个node.js应用程序正在接收包含文字NaN的JSON数据字符串,例如

然后你的NodeJS应用程序没有收到JSON,它正在接收类似JSON的文本.NaN不是有效的JSON令牌.

三种选择:

1.获取源以正确生成JSON

这显然是首选课程.数据不是JSON,应该修复,这将解决您的问题.

2. NaN以一种简单的方式容忍:

您可以null在解析之前替换它,例如:

var result = JSON.parse(yourString.replace(/\bNaN\b/g, "null"));
Run Code Online (Sandbox Code Playgroud)

...然后null在结果中处理s.但这是非常简单的,它不允许角色NaN可能出现在某个地方的字符串中.

或者,旋转Matt Ball的reviver想法(现已删除),您可以将其更改为特殊字符串(如"***NaN***"),然后使用reviver将其替换为真实NaN:

var result = JSON.parse(yourString.replace(/\bNaN\b/g, '"***NaN***"'), function(key, value) {
    return value === "***NaN***" ? NaN : value;
});
Run Code Online (Sandbox Code Playgroud)

...但是,假设角色NaN永远不会出现在合适的位置,那就有一点点简单的问题.

3.使用(颤抖!) eval

如果你知道并信任这些数据的来源并且没有可能在运输过程中被篡改,那么你可以eval用来解析它而不是JSON.parse.因为eval允许完整的JavaScript语法,包括NaN,这是有效的.希望我提醒大胆,让人们明白我只会在非常非常非常微小的情况下推荐这个.但同样,请记住eval允许任意执行代码,因此如果字符串被篡改的可能性,请不要使用它.

  • 假设文本"NaN"永远不会出现在字符串中.要做到这一点,Right Way(TM)需要解析JSON以确定无效令牌的位置 - 此时您也可以将解析树转换为对象.所以基本上,正确的解决方案是编写自己的容忍NaN的JSON-ish解析器. (4认同)
  • 我选择了选项 3,值得一提的是,您需要在输入中添加括号:`function myParseJSON(almost_json) { return eval("(" +most_json + ")") }` (2认同)

Den*_*ret 6

当您处理任何数学或行业数据时,NaN非常方便(通常无穷大也是如此)。它是自 IEEE754 以来的行业标准。

这显然就是为什么一些库,尤其是 GSON,让你将它们包含在它们生成的 JSON 中,从而失去了标准的纯度并获得了理智。

当您交换复杂的动态对象时,复兴和正则表达式解决方案在实际项目中不可靠。

并且eval也有问题,其中之一是当 JSON 字符串很大时它很容易在 IE 上崩溃,另一个是安全风险。

这就是为什么我写了一个特定的解析器(用于生产):JSON.parseMore


nir*_*msu 5

您可以使用JSON5库。来自项目页面的引用:

JSON5 数据交换格式 (JSON5) 是 JSON 的超集,旨在通过扩展其语法以包括来自 ECMAScript 5.1 的一些产品来减轻 JSON 的一些限制。

这个 JavaScript 库是 JSON5 解析和序列化库的官方参考实现。

如您所料,除其他外,它确实支持解析 NaN(与 Python 等序列化它们的方式兼容):

JSON5.parse("[1, 2, 3, NaN, 5, 6]")
> (6) [1, 2, 3, NaN, 5, 6]
Run Code Online (Sandbox Code Playgroud)