Подтвердить что ты не робот

Разбор "расслабленного" JSON без eval

Каков самый простой способ разобрать "расслабленный" JSON, но избегать зла eval?

Далее выдается сообщение об ошибке:

JSON.parse("{muh: 2}");

поскольку у правильного JSON должны быть указаны ключевые слова: {"muh": 2}


Мой пример использования - простой тестовый интерфейс, который я использую для написания команд JSON для моего сервера node. До сих пор я просто использовал eval, поскольку это просто тестовое приложение. Тем не менее, использование JSHint во всем проекте продолжает прослушивать меня об этом eval. Поэтому я бы хотел использовать безопасную альтернативу, которая по-прежнему допускает расслабленный синтаксис клавиш.

PS: Я не хочу писать парсер самостоятельно только для тестового приложения: -)

4b9b3361

Ответ 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
}

Ответ 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