Преобразование строки объекта в 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