1

感谢您的关注!

背景

我正在编写一些使用 JSON 服务的前端代码,该服务返回格式错误的 JSON。具体来说,键没有用引号括起来:

{foo: "bar"}

我无法控制服务,所以我正在纠正这个问题:

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

这给了我格式良好的 JSON:

{“富”:“酒吧”}

问题

但是,当我打电话时JSON.parse(scrubbedJson),我仍然收到错误消息。我怀疑这可能是因为整个 JSON 字符串都用双引号引起来,但我不确定。

更新

这已经解决了——上面的代码工作正常。我在返回的 JSON 正文中有一个流氓单引号。我把它弄出来了,现在一切都解析了。谢谢。任何帮助,将不胜感激。

4

5 回答 5

3

您可以完全避免使用正则表达式,并且仍然从格式错误的 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 (打开你的控制台)

于 2013-09-29T01:37:15.577 回答
2

这样的事情可能有助于修复 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')
于 2013-08-16T19:10:43.697 回答
0

我试图在 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, "$1\"$2\":");// all object names should be double quoted
var newObject = JSON.parse(newQuotedKeysString);

以下是正则表达式的细分:

  • ({|,)查找对象的开头,a{查找平面对象或,嵌入对象。
  • (?:\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 解析器允许名称使用的字符。如果您想在名称中允许更多字符(您可以这样做并且仍然有效),您可以改为使用([^'":]+)双引号或单引号或冒号以外的任何字符。你可以用这个表达式在这里有各种各样的东西,所以要小心。
  • 一个缺点是这种方法实际上改变了原始传入的数据(但我认为这就是你想要的?)。您可以围绕它进行编程以缓解此问题 - 取决于您的需求和可用资源。

希望这可以帮助。——约翰·L。

于 2014-08-05T18:42:32.030 回答
0

有一个项目可以处理 JSON 中的各种无效案例https://github.com/freethenation/durable-json-lint

于 2013-11-11T03:55:38.023 回答
-1

怎么样?

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

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

    return output;
}
于 2013-11-12T14:19:23.567 回答