在 JavaScript 中解析格式错误的 JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18280279/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Parsing malformed JSON in JavaScript
提问by Matt Cashatt
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:
我正在编写一些使用 JSON 服务的前端代码,该服务返回格式错误的 JSON。具体来说,键没有用引号括起来:
{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, '"": ');
This gives me well formed JSON:
这给了我格式良好的 JSON:
{"foo": "bar"}
{"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.
但是,当我调用 时JSON.parse(scrubbedJson)
,我仍然收到错误消息。我怀疑这可能是因为整个 JSON 字符串都用双引号括起来了,但我不确定。
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.
这已经解决了——上面的代码工作正常。我在返回的 JSON 正文中有一个流氓单引号。我把它弄出来了,现在一切都解析了。谢谢。任何帮助,将不胜感激。
回答by csuwldcat
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:
您可以完全避免使用正则表达式,而仍然使用以下简单技巧从格式错误的 JSON 字符串(不带引号的键、单引号等)中输出 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 ;)
Here's a demo:http://codepen.io/csuwldcat/pen/dfzsu(open your console)
这是一个演示:http : //codepen.io/csuwldcat/pen/dfzsu(打开你的控制台)
回答by Adam MacDonald
something like this may help to repair the json ..
这样的事情可能有助于修复 json ..
$str='{foo:"bar"}';
echo preg_replace('/({)([a-zA-Z0-9]+)(:)/','""',$str);
Output:
输出:
{"foo":"bar"}
EDIT:
编辑:
var str='{foo:"bar"}';
str.replace(/({)([a-zA-Z0-9]+)(:)/,'""')
回答by katzmopolitan
There is a project that takes care of all kinds of invalid cases in JSON https://github.com/freethenation/durable-json-lint
有一个项目可以处理 JSON 中的各种无效情况https://github.com/freethenation/durable-json-lint
回答by John L
I was trying to solve the same problem using a regEx in Javascript. I have an app written for Node.js to parse incoming JSON, but wanted a "relaxed" version of the parser (see following comments), since it is inconvenient to put quotes around every key (name). Here is my solution:
我试图在 Javascript 中使用正则表达式来解决同样的问题。我有一个为 Node.js 编写的应用程序来解析传入的 JSON,但想要一个“轻松”版本的解析器(请参阅以下评论),因为在每个键(名称)周围加上引号很不方便。这是我的解决方案:
var objKeysRegex = /({|,)(?:\s*)(?:')?([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*)(?:')?(?:\s*):/g;// look for object names
var newQuotedKeysString = originalString.replace(objKeysRegex, "\"\":");// 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.
({|,)
查找对象的开头,a{
用于平面对象或,
嵌入对象。(?:\s*)
找到但不记得空格(?:')?
找到但不记得单引号(稍后将替换为双引号)。将有零或其中之一。([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*)
是名称(或键)。以任何字母、下划线、$ 或点开头,后跟零个或多个字母数字字符或下划线、破折号、点或 $。- 最后一个字符
:
是将对象名称与值分隔开的字符。
Now we can use replace()
with some dressing to get our newly quoted keys:
现在我们可以使用replace()
一些敷料来获取我们新引用的键:
originalString.replace(objKeysRegex, "\"\":")
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
其中$1
或者是{
或,
根据对象是否被嵌入在另一个对象。 \"
添加双引号。 $2
是名字。\"
另一个双引号。并最终:
完成它。测试一下
{keyOne: "value1", $keyTwo: "value 2", key-3:{key4:18.34}}
output:
输出:
{"keyOne": "value1","$keyTwo": "value 2","key-3":{"key4":18.34}}
Some comments:
一些评论:
- 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 shortcoming is that this method actually changes the original incoming 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.
- 我还没有测试过这种方法的速度,但从我通过阅读其中一些条目收集的信息来看,使用正则表达式比使用正则表达式要快
eval()
- 对于我的应用程序,我限制了
([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*)
我的“宽松”版本 JSON 解析器允许使用的名称字符。如果您想在名称中允许更多字符(您可以这样做并且仍然有效),您可以改为使用([^'":]+)
双引号或单引号或冒号以外的任何内容。你可以用这个表达式在这里有各种各样的东西,所以要小心。 - 一个缺点是这种方法实际上更改了原始传入数据(但我认为这就是您想要的?)。您可以围绕它进行编程以缓解此问题 - 取决于您的需求和可用资源。
Hope this helps. -John L.
希望这可以帮助。-约翰·L。
回答by Guy
How about?
怎么样?
function fixJson(json) {
var tempString, tempJson, output;
tempString = JSON.stringify(json);
tempJson = JSON.parse(tempString);
output = JSON.stringify(tempJson);
return output;
}