admin管理员组

文章数量:1317915

Thanks for looking!

BACKGROUND

I am writing some front-end code that consumes a JSON service which is returning malformed JSON. Specifically, the keys are not surrounded with quotes:

{foo: "bar"}

I have NO CONTROL over the service, so I am correcting this like so:

var scrubbedJson = dirtyJson.replace(/(['"])?([a-zA-Z0-9_]+)(['"])?:/g, '"$2": ');

This gives me well formed JSON:

{"foo": "bar"}

Problem

However, when I call JSON.parse(scrubbedJson), I still get an error. I suspect it may be because the entire JSON string is surrounded in double quotes but I am not sure.

UPDATE

This has been solved--the above code works fine. I had a rogue single quote in the body of the JSON that was returned. I got that out of there and everything now parses. Thanks. Any help would be appreciated.

Thanks for looking!

BACKGROUND

I am writing some front-end code that consumes a JSON service which is returning malformed JSON. Specifically, the keys are not surrounded with quotes:

{foo: "bar"}

I have NO CONTROL over the service, so I am correcting this like so:

var scrubbedJson = dirtyJson.replace(/(['"])?([a-zA-Z0-9_]+)(['"])?:/g, '"$2": ');

This gives me well formed JSON:

{"foo": "bar"}

Problem

However, when I call JSON.parse(scrubbedJson), I still get an error. I suspect it may be because the entire JSON string is surrounded in double quotes but I am not sure.

UPDATE

This has been solved--the above code works fine. I had a rogue single quote in the body of the JSON that was returned. I got that out of there and everything now parses. Thanks. Any help would be appreciated.

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Aug 16, 2013 at 18:56 Matt CashattMatt Cashatt 24.2k29 gold badges82 silver badges114 bronze badges 8
  • Can you show what's actually returned by the service? Yes, if the entire string is surrounded by double quotes it's still not valid JSON. – Tamzin Blake Commented Aug 16, 2013 at 18:58
  • 1 Also, can you fix the service? – Tamzin Blake Commented Aug 16, 2013 at 18:59
  • You can assume that the following would be returned: "{"foo":"bar"}". I am terrible with regex. Do you know how this would be cured? – Matt Cashatt Commented Aug 16, 2013 at 18:59
  • Fixing the service is unfortunately not an option. I have no control over it. – Matt Cashatt Commented Aug 16, 2013 at 18:59
  • 1 You're almost there! You're on the right track preprocessing the JSON, just add another rule to remove the quotes at the beginning and end of the malformed JSON string. Also, if I were you, I would contact the service and send them a link to this question in order to help others, as well as encourage the service to fix the json output! – FredTheWebGuy Commented Aug 16, 2013 at 19:11
 |  Show 3 more ments

5 Answers 5

Reset to default 3

You can avoid using a regexp altogether and still output a JavaScript object from a malformed JSON string (keys without quotes, single quotes, etc), using this simple trick:

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

Here's a demo: http://codepen.io/csuwldcat/pen/dfzsu (open your console)

something like this may help to repair the json ..

$str='{foo:"bar"}';
echo preg_replace('/({)([a-zA-Z0-9]+)(:)/','$1"$2"${3}',$str);

Output:

{"foo":"bar"}

EDIT:

var str='{foo:"bar"}';
str.replace(/({)([a-zA-Z0-9]+)(:)/,'$1"$2"$3')

There is a project that takes care of all kinds of invalid cases in JSON https://github./freethenation/durable-json-lint

I was trying to solve the same problem using a regEx in Javascript. I have an app written for Node.js to parse ining JSON, but wanted a "relaxed" version of the parser (see following ments), since it is inconvenient to put quotes around every key (name). Here is my solution:

var objKeysRegex = /({|,)(?:\s*)(?:')?([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*)(?:')?(?:\s*):/g;// look for object names
var newQuotedKeysString = originalString.replace(objKeysRegex, "$1\"$2\":");// all object names should be double quoted
var newObject = JSON.parse(newQuotedKeysString);

Here's a breakdown of the regEx:

  • ({|,) looks for the beginning of the object, a { for flat objects or , for embedded objects.
  • (?:\s*) finds but does not remember white space
  • (?:')? finds but does not remember a single quote (to be replaced by a double quote later). There will be either zero or one of these.
  • ([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*) is the name (or key). Starts with any letter, underscore, $, or dot, followed by zero or more alpha-numeric characters or underscores or dashes or dots or $.
  • the last character : is what delimits the name of the object from the value.

Now we can use replace() with some dressing to get our newly quoted keys:

originalString.replace(objKeysRegex, "$1\"$2\":")

where the $1 is either { or , depending on whether the object was embedded in another object. \" adds a double quote. $2 is the name. \" another double quote. and finally : finishes it off. Test it out with

{keyOne: "value1", $keyTwo: "value 2", key-3:{key4:18.34}}

output:

{"keyOne": "value1","$keyTwo": "value 2","key-3":{"key4":18.34}}

Some ments:

  • I have not tested this method for speed, but from what I gather by reading some of these entries is that using a regex is faster than eval()
  • For my application, I'm limiting the characters that names are allowed to have with ([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*) for my 'relaxed' version JSON parser. If you wanted to allow more characters in names (you can do that and still be valid), you could instead use ([^'":]+) to mean anything other than double or single quotes or a colon. You can have all sorts of stuff in here with this expression, so be careful.
  • One shorting is that this method actually changes the original ining data (but I think that's what you wanted?). You could program around that to mitigate this issue - depends on your needs and resources available.

Hope this helps. -John L.

How about?

function fixJson(json) {
    var tempString, tempJson, output;

    tempString = JSON.stringify(json);
    tempJson = JSON.parse(tempString);
    output = JSON.stringify(tempJson);

    return output;
}

本文标签: regexParsing malformed JSON in JavaScriptStack Overflow