Разбор "расслабленного" JSON без eval
Каков самый простой способ разобрать "расслабленный" JSON, но избегать зла eval
?
Далее выдается сообщение об ошибке:
JSON.parse("{muh: 2}");
поскольку у правильного JSON должны быть указаны ключевые слова: {"muh": 2}
Мой пример использования - простой тестовый интерфейс, который я использую для написания команд JSON для моего сервера node. До сих пор я просто использовал eval
, поскольку это просто тестовое приложение. Тем не менее, использование JSHint во всем проекте продолжает прослушивать меня об этом eval
. Поэтому я бы хотел использовать безопасную альтернативу, которая по-прежнему допускает расслабленный синтаксис клавиш.
PS: Я не хочу писать парсер самостоятельно только для тестового приложения: -)
Ответы
Ответ 1
Вы уже знаете это, так как направили меня сюда, но я полагаю, что было бы хорошо документировать это здесь:
У меня давно было такое же желание писать "расслабленный" JSON, который все еще был действительным JS, поэтому я взял Дугласа Крокфорда без eval json_parse.js и расширил его для поддержки функций ES5:
https://github.com/aseemk/json5
Этот модуль доступен по npm и может быть использован в качестве замены для собственного метода JSON.parse()
. (Его stringify()
выводит обычный JSON.)
Надеюсь это поможет!
Ответ 2
Вы можете дезинфицировать JSON, используя регулярное выражение replace:
var badJson = "{muh: 2}";
var correctJson = badJson.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": ');
JSON.parse(correctJson);
Ответ 3
Это то, что я должен был сделать. Я добавил @ArnaudWeil ответ и добавил поддержку наличия :
в значениях:
var badJSON = '{one : "1:1", two : { three: \'3:3\' }}';
var fixedJSON = badJSON
// Replace ":" with "@[email protected]" if it between double-quotes
.replace(/:\s*"([^"]*)"/g, function(match, p1) {
return ': "' + p1.replace(/:/g, '@[email protected]') + '"';
})
// Replace ":" with "@[email protected]" if it between single-quotes
.replace(/:\s*'([^']*)'/g, function(match, p1) {
return ': "' + p1.replace(/:/g, '@[email protected]') + '"';
})
// Add double-quotes around any tokens before the remaining ":"
.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?\s*:/g, '"$2": ')
// Turn "@[email protected]" back into ":"
.replace(/@[email protected]/g, ':')
;
console.log('Before: ' + badJSON);
console.log('After: ' + fixedJSON);
console.log(JSON.parse(fixedJSON));
Ответ 4
Если вы не можете указывать ключи при записи строки, вы можете вставлять кавычки перед использованием JSON.parse -
var s= "{muh: 2,mah:3,moh:4}";
s= s.replace(/([a-z][^:]*)(?=\s*:)/g, '"$1"');
var o= JSON.parse(s);
/* returned value:[object Object] */
JSON.stringify(o)
/* returned value: (String){
"muh":2, "mah":3, "moh":4
}
Ответ 5
JSON5 выглядит довольно хорошо, но это Библиотека relaxed-json также выглядит неплохо.
Ответ 6
Вы также можете использовать NPM действительно-relaxed-json (https://www.npmjs.com/package/really-relaxed-json), который идет дальше и не допускает запятых, висячих запятых, комментариев, многострочных строк и т.д.
Здесь спецификация
http://www.relaxedjson.org
И некоторые онлайн-парсеры:
http://www.relaxedjson.org/docs/converter.html
Предустановленный с "плохой JSON"
{one : "1:1", two : { three: '3:3' }}
Плохой JSON
Предустановленный даже с "худшим json" (без запятых)
{one : '1:1' two : { three: '3:3' }}
Хуже JSON
Предустановленный с 'ужасным JSON' (без запятых, без кавычек и экранированных двоеточий)
{one : 1\:1 two : {three : 3\:3}}
Ужасный JSON