[英]Parsing malformed JSON in JavaScript
谢谢你的期待!
我正在编写一些使用JSON服务的前端代码,该服务返回格式错误的JSON。 具体来说,键不包含引号:
{foo: "bar"}
我无法控制服务,所以我这样纠正:
var scrubbedJson = dirtyJson.replace(/(['"])?([a-zA-Z0-9_]+)(['"])?:/g, '"$2": ');
这给了我很好的JSON:
{“foo”:“bar”}
但是,当我调用JSON.parse(scrubbedJson)
,我仍然会收到错误。 我怀疑它可能是因为整个JSON字符串被双引号包围但我不确定。
这已经解决了 - 上面的代码工作正常。 我在返回的JSON正文中有一个流氓单引号。 我把它从那里拿出来,现在一切都解析了。 谢谢。 任何帮助,将不胜感激。
您可以完全避免使用正则表达式,并仍然使用这个简单的技巧从错误的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 ;)
这是一个演示: http : //codepen.io/csuwldcat/pen/dfzsu (打开你的控制台)
这样的事情可能有助于修复json ..
$str='{foo:"bar"}';
echo preg_replace('/({)([a-zA-Z0-9]+)(:)/','$1"$2"${3}',$str);
输出:
{"foo":"bar"}
编辑:
var str='{foo:"bar"}';
str.replace(/({)([a-zA-Z0-9]+)(:)/,'$1"$2"$3')
有一个项目可以处理JSON中的各种无效案例https://github.com/freethenation/durable-json-lint
我试图在Javascript中使用regEx来解决同样的问题。 我有一个为Node.js编写的应用程序来解析传入的JSON,但是想要解析器的“宽松”版本(参见下面的注释),因为在每个键(名称)周围放置引号是不方便的。 这是我的解决方案:
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);
以下是regEx的细分:
({|,)
查找的对象的开头,一个{
为平面物体或,
为嵌入的对象。 (?:\\s*)
找到但不记得空格 (?:')?
发现但不记得单引号(稍后将被双引号替换)。 这些将是零或其中之一。 ([A-Za-z_$\\.][A-Za-z0-9_ \\-\\.$]*)
是名称(或键)。 从任何字母,下划线,$或点开始,后跟零个或多个字母数字字符或下划线或短划线或点或$。 :
是从值中分隔对象名称的内容。 现在我们可以使用replace()
和一些修饰来获取我们新引用的键:
originalString.replace(objKeysRegex, "$1\"$2\":")
其中$1
是{
或者,
取决于对象是否嵌入在另一个对象中。 \\"
添加一个双引号。 $2
是名字。 \\"
另一个双引号。 最后:
完成它。 测试一下
{keyOne: "value1", $keyTwo: "value 2", key-3:{key4:18.34}}
输出:
{"keyOne": "value1","$keyTwo": "value 2","key-3":{"key4":18.34}}
一些评论:
eval()
更快 ([A-Za-z_$\\.][A-Za-z0-9_ \\-\\.$]*)
用于我的“宽松”版本JSON解析器。 如果你想在名字中允许更多的字符(你可以这样做并且仍然有效),你可以使用([^'":]+)
来表示除双引号或单引号或冒号以外的任何字符。你可以拥有所有字符这个表达式在这里有各种各样的东西,所以要小心。 希望这可以帮助。 -John L.
怎么样?
function fixJson(json) {
var tempString, tempJson, output;
tempString = JSON.stringify(json);
tempJson = JSON.parse(tempString);
output = JSON.stringify(tempJson);
return output;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.