Преобразование строки объекта в JSON
Как преобразовать строку, которая описывает объект в строку JSON, используя JavaScript (или jQuery)?
например: Преобразуйте это (НЕ действительная строка JSON):
var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }"
в это:
str = '{ "hello": "world", "places": ["Africa", "America", "Asia", "Australia"] }'
Я хотел бы избежать использования eval()
, если это возможно.
Ответы
Ответ 1
Если строка из надежного источника, вы можете использовать eval
, а затем JSON.stringify
результат. Вот так:
var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
var json = JSON.stringify(eval("(" + str + ")"));
Обратите внимание, что когда вы eval
литерал объекта, он должен быть заключен в круглые скобки, в противном случае фигурные скобки обрабатываются как блок вместо объекта.
Я также согласен с комментариями по вопросу о том, что было бы намного лучше просто закодировать объект в действительном JSON для начала и избежать необходимости синтаксического анализа, кодирования, а затем, по-видимому, разобрать его снова. HTML поддерживает атрибуты с одним кавычком (просто убедитесь, что HTML-кодирование любых одинарных кавычек внутри строк).
Ответ 2
Ваша строка недействительна JSON, поэтому JSON.parse
(или jQuery $.parseJSON
) не будет работать.
Одним из способов было бы использовать eval
для "разбора" "недействительного" JSON, а затем stringify
его "преобразовать" его в действительный JSON.
var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }"
str = JSON.stringify(eval('('+str+')'));
Я предлагаю вместо того, чтобы пытаться "исправить" ваш недействительный JSON, вы начинаете с действительного JSON в первую очередь. Как создается str
, он должен быть исправлен там, прежде чем он сгенерирован, а не после.
EDIT. Вы сказали (в комментариях) эта строка хранится в атрибуте данных:
<div data-object="{hello:'world'}"></div>
Я предлагаю вам исправить это здесь, так что это может быть только JSON.parse
d. Во-первых, оба ключа и значения должны быть указаны в двойных кавычках. Он должен выглядеть (допустимы однократные кавычки в HTML):
<div data-object='{"hello":"world"}'></div>
Теперь вы можете просто использовать JSON.parse
(или jQuery $.parseJSON
).
var str = '{"hello":"world"}';
var obj = JSON.parse(str);
Ответ 3
jQuery.parseJSON
str = jQuery.parseJSON(str)
Изменить. Это означает, что у вас есть действительная строка JSON
Ответ 4
Используйте простой код по следующей ссылке:
http://msdn.microsoft.com/es-es/library/ie/cc836466%28v=vs.94%29.aspx
var jsontext = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}';
var contact = JSON.parse(jsontext);
и наоборот
var str = JSON.stringify(arr);
Ответ 5
Я надеюсь, что эта небольшая функция преобразует недопустимую строку JSON в действительный.
function JSONize(str) {
return str
// wrap keys without quote with valid double quote
.replace(/([\$\w]+)\s*:/g, function(_, $1){return '"'+$1+'":'})
// replacing single quote wrapped ones to double quote
.replace(/'([^']+)'/g, function(_, $1){return '"'+$1+'"'})
}
Результат
var invalidJSON = "{ hello: 'world',foo:1, bar : '2', foo1: 1, _bar : 2, $2: 3, 'xxx': 5, \"fuz\": 4, places: ['Africa', 'America', 'Asia', 'Australia'] }"
JSON.parse(invalidJSON)
//Result: Uncaught SyntaxError: Unexpected token h VM1058:2
JSON.parse(JSONize(invalidJSON))
//Result: Object {hello: "world", foo: 1, bar: "2", foo1: 1, _bar: 2…}
Ответ 6
Следует использовать с осторожностью (из-за eval()
):
function strToJson(str) {
eval("var x = " + str + ";");
return JSON.stringify(x);
}
вызывать как:
var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
alert( strToJson(str) );
Ответ 7
Отказ от ответственности: не пытайтесь это делать дома или для чего-то, что требует от вас других разработчиков:
JSON.stringify(eval('(' + str + ')'));
Там, я сделал это.
Постарайтесь не делать этого, eval - ПЛОХО для вас. Как сказано выше, используйте прокладку Crockford JSON для старых браузеров (IE7 и ниже)
Этот метод требует, чтобы ваша строка была действительной javascript, которая будет преобразована в объект javascript, который затем может быть сериализован в JSON.
edit: исправлено как предложено Rocket.
Ответ 8
Я поместил свой ответ для кого-то, кто заинтересован в этом старом потоке.
Я создал HTML5 data- * parser для плагина jQuery и demo, которые преобразуют неверную строку JSON в объект JavaScript без использования eval()
.
Он может передать атрибуты данных HTML5 ниже:
<div data-object='{"hello":"world"}'></div>
<div data-object="{hello:'world'}"></div>
<div data-object="hello:world"></div>
в объект:
{
hello: "world"
}
Ответ 9
У Дугласа Крокфорда есть конвертер, но я не уверен, что он поможет с плохим JSON в хорошем JSON.
https://github.com/douglascrockford/JSON-js
Ответ 10
Вам нужно использовать "eval", затем JSON.stringify, а затем JSON.parse для результата.
var errorString= "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
var jsonValidString = JSON.stringify(eval("(" + errorString+ ")"));
var JSONObj=JSON.parse(jsonValidString);
![enter image description here]()
Ответ 11
Вам нужно написать круглые скобки, потому что без них eval
будет рассматривать код внутри фигурных скобок как блок команд.
var i = eval("({ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] })");
Ответ 12
Там гораздо более простой способ выполнить этот подвиг, просто захватить атрибут onclick фиктивного элемента, чтобы принудительно вернуть вашу строку в качестве объекта JavaScript:
var jsonify = (function(div){
return function(json){
div.setAttribute('onclick', 'this.__json__ = ' + json);
div.click();
return div.__json__;
}
})(document.createElement('div'));
// Let say you had a string like '{ one: 1 }' (malformed, a key without quotes)
// jsonify('{ one: 1 }') will output a good ol' JS object ;)
Здесь демо: http://codepen.io/csuwldcat/pen/dfzsu (откройте консоль)
Ответ 13
Ваша лучшая и самая безопасная ставка - JSON5 - JSON for Humans. Он создан специально для этого варианта использования.
const result = JSON5.parse("{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }");
console.log(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/json5/0.5.1/json5.min.js"></script>
Ответ 14
В приведенном выше простом примере вы можете сделать это с помощью двух простых замен регулярных выражений:
var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
str.replace(/(\w+):/g, '"$1":').replace(/'/g, '"');
=> '{ "hello": "world", "places": ["Africa", "America", "Asia", "Australia"] }'
Большое предостережение: этот наивный подход предполагает, что у объекта нет строк, содержащих символ '
или :
. Например, я не могу придумать хороший способ преобразовать следующую строку объекта в JSON без использования eval
:
"{ hello: 'world', places: [\"America: The Progressive Nightmare\"] }"
Ответ 15
Просто для удобства, вы можете конвертировать вашу строку с помощью babel-standalone
var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
function toJSON() {
return {
visitor: {
Identifier(path) {
path.node.name = '"' + path.node.name + '"'
},
StringLiteral(path) {
delete path.node.extra
}
}
}
}
Babel.registerPlugin('toJSON', toJSON);
var parsed = Babel.transform('(' + str + ')', {
plugins: ['toJSON']
});
var json = parsed.code.slice(1, -2)
console.log(JSON.parse(json))
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
Ответ 16
var str = "{привет: 'мир', мест: ['Африка', 'Америка', 'Азия', 'Австралия']}" var fStr = str.replace(/([Az] *) (:)/g, '"$ 1":').replace(/'/g, "\" ")
console.log(JSON.parse(Fstr)) ![enter image description here]()
Извините, я на своем телефоне, вот картинка.
Ответ 17
Решение с одним регулярным выражением без использования eval:
str.replace(/([\s\S]*?)(')(.+?)(')([\s\S]*?)/g, "$1\"$3\"$5")
Я считаю, что это должно работать для нескольких строк и всех возможных вхождений (/g флаг) "строки" в одинарных кавычках, заменяемых "строкой" в двойных кавычках.
Ответ 18
Может быть, вы должны попробовать это:
str = jQuery.parseJSON(str)
Ответ 19
var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
var json = JSON.stringify(eval("(" + str + ")"));
Ответ 20
Использование новой функции() лучше, чем eval, но все же следует использовать только с безопасным вводом.
const parseJSON = obj => Function('"use strict";return (' + obj + ')')();
console.log(parseJSON("{a:(4-1), b:function(){}, c:new Date()}"))
// outputs: Object { a: 3, b: b(), c: Date 2019-06-05T09:55:11.777Z }
Источники: MDN, 2ality