Как разобрать строку JSON, содержащую "NaN"в узле.Яш
есть узел.приложение js, которое получает строки данных JSON, содержащие литерал NaN, например
"[1, 2, 3, NaN, 5, 6]"
этот сбой JSON.parse(...)
в узел.js. Я хотел бы разобрать его, если смогу, на объект.
Я знаю NaN
не является частью спецификации JSON. Большинство так ссылки (отправка NaN в json) предложите исправить выход.
здесь, хотя данные производятся на сервере, который я не контролирую, это коммерческая библиотека Java, где я могу видеть исходный код. И это произведено библиотекой Gson Google:
private Gson gson = (new GsonBuilder().serializeSpecialFloatingPointValues().create());
...
gson.toJson(data[i], Vector.class, jsonOut)
так что это похоже на законный источник. И по Gson API Javadoc он говорит, что я должен быть в состоянии разобрать его:
раздел 2.4 спецификации JSON запрещает специальные двойные значения (НАН, Бесконечность, - Бесконечность). Однако спецификация Javascript (см. раздел 4.3.20, 4.3.22, 4.3.23) допускает эти значения как действительные Значения Javascript. Более того, большинство движков JavaScript будут принять это особого значения в JSON без проблем. Итак, на практическом уровне, это имеет смысл принять эти значения как допустимые JSON, даже если JSON спецификация запрещает их.
несмотря на это, это не удается в обоих узлах.js и Chrome:JSON.parse('[1,2,3,NaN,"5"]')
есть ли флаг для установки в JSON.метод Parse()? Или альтернативный парсер, который принимает NaN
как буквальное?
Я некоторое время гуглил, но, похоже, не могу найти документ на этом вопрос.
3 ответов
есть узел.приложение js, которое получает строки данных JSON, содержащие литерал NaN, например
тогда ваше приложение NodeJS не прием JSON, он получает текст, который смутно похож на JSON. NaN
не является допустимым токеном JSON.
три варианта:
1. Получите источник, чтобы правильно создать JSON
это, очевидно, предпочтительнее. Данные не JSON, это должно быть исправлено, что исправит вашу проблему.
2. Терпеть NaN
в простодушном виде:
вы можете заменить его с null
перед разбором, например:
var result = JSON.parse(yourString.replace(/\bNaN\b/g, "null"));
...а потом обрабатывать null
s в результате. Но это очень просто, это не учитывает возможность того, что персонажи NaN
может появиться в строке где-то.
поочередно, вращая Мэтт мяч reviver
идея (ныне удаленный), вы может изменить его на специальную строку (например,"***NaN***"
), а затем используйте reviver, чтобы заменить это на real NaN
:
var result = JSON.parse(yourString.replace(/\bNaN\b/g, '"***NaN***"'), function(key, value) {
return value === "***NaN***" ? NaN : value;
});
...но у этого есть та же проблема быть немного простодушным, предполагая, что персонажи NaN
никогда не появляйтесь в соответствующем месте.
3. Использовать (страшно!) eval
если вы знаете и доверяете источнику этих данных, и нет никакой возможности его подделки в транзит, тогда вы могли бы использовать eval
распарсить вместо JSON.parse
. С eval
обеспечивает полный синтаксис JavaScript, в том числе NaN
, который работает. Надеюсь, я сделал предостережение достаточно смелым, чтобы люди поняли, что я бы рекомендовал это только в очень, очень,очень мизерный процент ситуаций. Но опять же, помните eval
позволяет произвольное выполнение кода, поэтому, если есть какая-либо возможность изменения строки, Не используйте ее.
когда вы имеете дело с чем-либо математическим или с отраслевыми данными,NaN
ужасно удобно (и часто бесконечности тоже). И это отраслевой стандарт с IEEE754.
очевидно, поэтому некоторые библиотеки, особенно GSON, позволяют включать их в JSON, который они производят, теряя стандартную чистоту и обретая здравомыслие.
решения Revival и regex не надежно используются в реальном проекте при обмене сложными динамическими объектами.
и eval
также имеет проблемы, один из них-тот факт, что он склонен к сбою в IE, когда строка JSON большая, другой-риски безопасности.
вот почему я написал конкретный парсер (используемые в производстве) : в формате JSON.parseMore
правильным решением является перекомпиляция анализатора и внесение логического флага "allowNan" в исходную базу. Это решение, которое есть в других библиотеках (на ум приходит python).
хорошие библиотеки JSON будут разрешительно анализировать почти все, что смутно напоминает JSON с набором правильных флагов (JSON perl.pm является особенно гибким)... но при написании сообщения они производят стандартный JSON.
IE: оставьте номер чище, чем вы его нашли.