如何为 Javascript 中的 NaN 调整 JSON.Parser?

How to adapt JSON.Parser for NaN in Javascript?

我正在尝试为 NaN 调整 JSON.Parse()。

console.log(JSON.parse('{"n": 1}'));
console.log(JSON.parse('{"n": NaN}'));

第一个是{n:1}。

第 2 个出现错误 Unexpected token N in JSON。 我想将 NaN 更改为 0,例如 {n: 0}

我找到了一个从头开始创建 JSON 解析器的资源。 https://lihautan.com/json-parser-with-javascript/#implementing-the-parser

很好,他将键和值分开,这样我就可以只检查值是否存在 NaN 并修复它。 但问题是我不知道我可以把 NaNParser() 和过程放在哪里。因为参数看起来是 1 乘 1 个字符。

如果你能给我一些建议,这对我很有帮助。 https://codesandbox.io/s/json-parser-with-error-handling-hjwxk?from-embed

“Hacky”解决方案:

var json = '{"n": NaN}';

var object = JSON.parse(json.replace("NaN", "\"NaN\""));
for(var key in object)
{
    if(object[key] == "NaN")
    {
        object[key] = NaN;
    }
}

console.log(object);

这会将 JSON 中的所有 NaN 值替换为字符串“NaN”,然后通过 JSON.parse 运行它,然后 re-replaces 对象中的所有“NaN”字符串实际 NaN.

上下文

注意 JSON.stringify({"n": NaN}) 输出:'{"n":null}'

这意味着:

  • NaN 不是有效的序列化值。
  • 默认转换为null而不是0(因为它不是数字)

解决方案

也许最快的方法是在解析之前简单地替换所有 NaN 值。

const input = '{"o": 1, "n": NaN, "m": "test"}'

const output = input.replace(/(:\s*)NaN(\s*[,}])/, 'null')

console.log(output) // prints: '{"o": 1, "n": null, "m": "test"}'

或者您可以在终端中使用 sed

sed -e "s/pattern/replacement/g" <input.txt >output.txt

如果您需要在源中为 NaN 的地方生成零值的 JSON,您可以在本机 JSON.stringify

期间使用非常简单的序列化程序(“替换程序”)

console.log(
  JSON.stringify(
    // source data:
    {
      a: 1,
      b: NaN
    },
    // "replacer":
    function(key, value) {
      if (Number.isNaN(value)) {
        return 0
      }
      return value
    },
    // optional, indent character for formatting:
    "\t"
  )
)

要保留 NaN 值,您必须提供自定义替换器,该替换器将生成一些在语法上有效的 JSON 字符串中表示它的独特结构,并在执行 JSON.parse 取回它:

var original_data = {
    a: 1,
    NaN: NaN,
    NaNaNaNa: {
        Batman: true,
        baNaNa: NaN,
    }
}
const extra_type_value_key = "__value__";
const NaN_signal = "NaN, dude";
const NaN_representation = { [extra_type_value_key]: NaN_signal };
function replacer(key, value) {
    if (Number.isNaN(value)) {
        return NaN_representation;
    }
    return value
}
const data_JSON_string = JSON.stringify(original_data, replacer, "\t");
console.log("Data as JSON string:", data_JSON_string);
function reviver(key, value) {
    if (value && value[extra_type_value_key] && value[extra_type_value_key] === NaN_signal) {
        return NaN
    }
    return value
}
const data_POJO = JSON.parse(data_JSON_string, reviver, "\t");
console.log("Object from JSON string, should be same as original_data", data_POJO);
// unrelated
onload=()=>{with(document.querySelector('div').style)top=0,maxHeight='none'}

此外,出于类似的目的,使用 JSON-like 字符串的邪恶 eval 的黑暗实践将起作用:

var original_data_string = `{
  a: 1,
  b: NaN,
  NaNaNa: {
    Batman: NaN,
    baNaNa: 3,
    NaN: 4
  }
}`;

var data_object = eval(`(${original_data_string})`);

console.log(data_object);


看在上帝的份上,不要对 JSON 源字符串进行正则表达式替换,尤其是当您不知道数据的形状时!

I have no idea where I can put the NaNParser() and the process.

您在代码沙箱中使用的 Tan Li Hau fakeParseJSON 中有 parseValue 函数。教它识别 NaN 似乎就像在其中添加一个 parseKeyword 调用一样简单:

parseKeyword("NaN", NaN)

或者,既然你

And I want to change NaN to 0

parseKeyword("NaN", 0)

See fork.