web-dev-qa-db-ja.com

Node.jsで「NaN」を含むJSON文字列を解析する方法

次のようなリテラルNaNを含むJSONデータ文字列を受信するnode.jsアプリがあります。

_ "[1, 2, 3, NaN, 5, 6]"
_

これにより、Node.jsのJSON.parse(...)がクラッシュします。私がオブジェクトにできる場合は、それを解析したいと思います。

NaNはJSON仕様の一部ではないことを私は知っています。ほとんどのSOリンク( jsonでNaNを送信 )は出力を修正することを提案します。

ここでは、データは私が制御していないサーバーで生成されていますが、ソースコードを表示できる商用Javaライブラリによって生成されています。また、GoogleのGsonライブラリによって生成されています。

_private Gson gson = (new GsonBuilder().serializeSpecialFloatingPointValues().create()); 
... 
gson.toJson(data[i], Vector.class, jsonOut)
_

ですから、それは正当な情報源のようです。そして Gson API Javadoc によれば、それを解析できるはずです。

JSON仕様のセクション2.4では、特別なdouble値(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にエンコードする方法は?

20
prototype

次のようなリテラルNaNを含むJSONデータ文字列を受信するnode.jsアプリがあります。

次に、NodeJSアプリは受信しません[〜#〜] json [〜#〜] を受信しますJSONのような。 NaNは有効なJSONトークンではありません。

3つのオプション:

1.ソースを取得してJSONを正しく生成する

これは明らかに好ましいコースです。データはJSONではないため、修正する必要があります。これにより、問題が修正されます。

2.単純な方法でNaNを許容します。

解析する前に、nullに置き換えることができます。例:

var result = JSON.parse(yourString.replace(/\bNaN\b/g, "null"));

...そして結果のnullsを処理します。しかし、それは非常に単純な考え方であり、文字NaNが文字列のどこかに現れる可能性を考慮に入れていません。

または、MattBallのreviverアイデア(現在は削除されています)を回転させて、特別な文字列("***NaN***"など)に変更してから、リバイバーを使用することもできます。これを実際のNaNに置き換えるには:

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

...しかし、文字NaNが適切な場所に表示されないと仮定すると、少し単純であるという同じ問題があります。

3。(shudder!)evalを使用します

このデータのソースを知っていて信頼していて、転送中に改ざんされる可能性がない場合、その後、JSON.parseの代わりにevalを使用して解析できます。 evalは、NaNを含む完全なJavaScript構文を許可するため、機能します。うまくいけば、私がこれを非常に、非常に、非常にごくわずかな割合の状況でのみ推奨することを人々が理解できるように、警告を大胆にした。ただし、evalはコードの任意の実行を許可するため、文字列が改ざんされている可能性がある場合は使用しないでください。

33
T.J. Crowder

数学的または業界データを扱う場合、NaNは非常に便利です(多くの場合、無限大も便利です)。そしてそれはIEEE754以来の業界標準です。

そのため、GSONなどの一部のライブラリでは、ライブラリを生成するJSONに含めることができるため、標準の純粋さが失われ、健全性が高まります。

複雑な動的オブジェクトを交換する場合、実際のプロジェクトでリバイバルソリューションと正規表現ソリューションを確実に使用することはできません。

また、evalにも問題があります。その1つは、JSON文字列が大きい場合にIEでクラッシュする傾向があるという事実であり、もう1つはセキュリティリスクです。

そのため、特定のパーサー(本番環境で使用)を作成しました: JSON.parseMore

4
Denys Séguret

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]
1
nirvana-msu

正しい解決策は、パーサーを再コンパイルし、「allowNan」ブールフラグをソースベースに提供することです。これは他のライブラリが持っている解決策です(Pythonが思い浮かびます)。

優れたJSONライブラリは、適切なフラグが設定されたJSONに漠然と似ているものを許容的に解析します(PerlのJSON.pmは特に柔軟性があります)...しかし、メッセージを書き込むと、標準のJSONが生成されます。

IE:見つけたよりも部屋をきれいにしておいてください。

0
Erik Aronesty