Konwertuj łańcuch obiektów na JSON

Jak mogę przekonwertować łańcuch opisujący obiekt na łańcuch JSON za pomocą JavaScript (lub jQuery)?

Np: Convert this (NOT {[7] } a valid JSON string):

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }"

Do tego:

str = '{ "hello": "world", "places": ["Africa", "America", "Asia", "Australia"] }'
Chciałbym uniknąć używania eval(), jeśli to możliwe.
Author: BuZZ-dEE, 2012-01-27

19 answers

Jeśli łańcuch pochodzi z zaufanego źródła , możesz użyć eval, a następnie JSON.stringify wyniku. Tak:

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
var json = JSON.stringify(eval("(" + str + ")"));

Zauważ, że gdy eval obiekt jest literalny, musi być zawinięty w nawiasy, w przeciwnym razie klamry są przetwarzane jako blok zamiast obiektu.

Zgadzam się również z komentarzami pod pytaniem, że znacznie lepiej byłoby po prostu zakodować obiekt w poprawnym JSON na początek i uniknąć konieczności parsowania, kodowania, a następnie prawdopodobnie parsowania go ponownie. HTML obsługuje pojedyncze cytowane atrybuty(pamiętaj tylko, aby kodować pojedyncze cudzysłowy wewnątrz łańcuchów).

 167
Author: Matthew Crumley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-27 17:07:25

Twój łańcuch nie jest poprawny JSON, więc JSON.parse (lub $.parseJSON jQuery) nie będzie działać.

Jednym ze sposobów byłoby użycie eval do "parsowania" "nieprawidłowego" JSONA, a następnie stringify do "przekonwertowania" go na poprawny JSON.

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }"
str = JSON.stringify(eval('('+str+')'));

Sugeruję, aby zamiast próbować "naprawić" swój nieprawidłowy JSON, zacząć od poprawnego JSON w pierwszej kolejności. W jaki sposób str jest generowany, powinno być tam naprawione, zanim zostanie wygenerowane, a nie po.

EDIT : powiedziałeś (w komentarzach), że ten ciąg jest przechowywany w atrybut danych:

<div data-object="{hello:'world'}"></div>

Proponuję naprawić to tutaj, więc może to być po prostu JSON.parse d. Po pierwsze, zarówno klucze, jak i wartości muszą być cytowane w podwójnych cudzysłowach. Powinno to wyglądać tak (pojedyncze cytowane atrybuty w HTML są poprawne):

<div data-object='{"hello":"world"}'></div>

Teraz możesz po prostu użyć JSON.parse (lub jQuery $.parseJSON).

var str = '{"hello":"world"}';
var obj = JSON.parse(str);
 107
Author: Rocket Hazmat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-27 16:48:00

JQuery.parseJSON

str = jQuery.parseJSON(str)

Edit. Jest to pod warunkiem, że masz poprawny łańcuch JSON

 49
Author: Farmor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-27 16:15:22

Użyj prostego kodu w linku poniżej:

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);

I odwrotnie

var str = JSON.stringify(arr);
 38
Author: Ronald,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-09 09:22:12

Mam nadzieję, że ta mała funkcja zamieni nieprawidłowy łańcuch JSON na poprawny.

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+'"'})         
}

Wynik

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…}
 22
Author: allenhwkim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-10 03:26:40

Stosować ostrożnie (ze względu na eval()):

function strToJson(str) {
  eval("var x = " + str + ";");
  return JSON.stringify(x);
}

Wywołanie jako:

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
alert( strToJson(str) );
 9
Author: Tomalak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-27 17:13:12

Disclaimer: nie próbuj tego w domu, ani na cokolwiek, co wymaga, aby inni deweloperzy traktowali cię poważnie:

JSON.stringify(eval('(' + str + ')'));
Udało mi się.
Postaraj się tego nie robić, eval jest dla ciebie zły. Jak wspomniano powyżej, użyj JSON shim Crockforda dla starszych przeglądarek (IE7 i under)

Ta metoda wymaga, aby łańcuch znaków był poprawny javascript , który zostanie przekonwertowany do obiektu javascript, który może być serializowany do JSON.

edit: Naprawiono zgodnie z sugestią rakiety.

 4
Author: gonchuki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-27 16:19:39

Zamieszczam odpowiedź dla kogoś, kto jest zainteresowany tym starym wątkiem.

Stworzyłem HTML5 data-* parser dla wtyczki jQuery i demo , które konwertują zniekształcony łańcuch JSON do obiektu JavaScript bez użycia eval().

Może przekazać atrybuty HTML5 data - * poniżej:

<div data-object='{"hello":"world"}'></div>
<div data-object="{hello:'world'}"></div>
<div data-object="hello:world"></div>

Do obiektu:

{
    hello: "world"
}
 4
Author: tokkonopapa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-19 06:07:50

Douglas Crockford ma konwerter, ale nie jestem pewien, czy pomoże to ze złym JSONEM na dobry JSON.

Https://github.com/douglascrockford/JSON-js

 2
Author: Seth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-27 16:15:18

Musisz pisać nawiasy okrągłe, ponieważ bez nich eval będzie traktował kod wewnątrz nawiasów klamrowych jako blok poleceń.

var i = eval("({ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] })");
 1
Author: kuboslav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-27 16:26:12

Jest o wiele prostszy sposób na wykonanie tego wyczynu, po prostu przejmij atrybut onclick atrybutu atrapy elementu, aby wymusić powrót łańcucha jako obiektu JavaScript:

var jsonify = (function(div){
  return function(json){
    div.setAttribute('onclick', 'this.__json__ = ' + json);
    div.click();
    return div.__json__;
  }
})(document.createElement('div'));

// Let's say you had a string like '{ one: 1 }' (malformed, a key without quotes)
// jsonify('{ one: 1 }') will output a good ol' JS object ;)

Oto demo: http://codepen.io/csuwldcat/pen/dfzsu (otwórz konsolę)

 1
Author: csuwldcat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-28 16:07:47

Musisz użyć "eval", a następnie JSON.stringify następnie JSON.przeanalizuj wynik.

 var errorString= "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
 var jsonValidString = JSON.stringify(eval("(" + errorString+ ")"));
 var JSONObj=JSON.parse(jsonValidString);

Tutaj wpisz opis obrazka

 1
Author: Negi Rox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-02 10:24:37

Twoim najlepszym i najbezpieczniejszym zakładem będzie JSON5 - JSON dla ludzi . Został stworzony specjalnie dla tego przypadku użycia.

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>
 1
Author: dereli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-02 10:48:12

Dla prostego przykładu powyżej, możesz to zrobić używając 2 prostych regex zastępuje:

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
str.replace(/(\w+):/g, '"$1":').replace(/'/g, '"');
 => '{ "hello": "world", "places": ["Africa", "America", "Asia", "Australia"] }'

Duże zastrzeżenie : to naiwne podejście zakłada, że obiekt nie ma ciągów zawierających znak ' lub :. Na przykład, nie mogę wymyślić dobrego sposobu, aby przekonwertować następujący obiekt-string do JSON bez użycia eval:

"{ hello: 'world', places: [\"America: The Progressive's Nightmare\"] }"
 0
Author: Topher Hunt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-27 12:57:31

Tylko dla dziwactw, możesz przekonwertować swój ciąg za pomocą 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>
 0
Author: Moritz Roessler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-27 22:46:45

Var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }" var fStr = str .replace (/([a-z]*) (:) / g, '"$1":') .replace(/'/g,"\"")

Konsola.log(JSON.parse(fStr))Tutaj wpisz opis obrazka

Przepraszam, że rozmawiam przez telefon, tu jest zdjęcie.

 0
Author: Francis Leigh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-01 17:42:02

Rozwiązanie z jednym regex i nie używając eval:

str.replace(/([\s\S]*?)(')(.+?)(')([\s\S]*?)/g, "$1\"$3\"$5")

To powinno działać dla wielu linii i wszystkich możliwych wystąpień (flaga / g) pojedynczego cudzysłowu 'string' zastąpionego podwójnym cudzysłowem "string".

 0
Author: Chaitanya P,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-02 05:49:53
var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
var json = JSON.stringify(eval("(" + str + ")"));
 0
Author: praveenkumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-02 12:11:01

Może musisz spróbować tego:

str = jQuery.parseJSON(str)
 -1
Author: howdyhyber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-02 07:45:16