正则表达式在javascript中的键周围添加双引号

时间:2011-01-30 15:42:02

标签: javascript regex json

我正在使用jQuery的getJSON函数来发出请求并处理JSON响应。问题是我回来的反应是不正确的,我无法改变它。响应看起来像这样:

{
    aNumber: 200,    
    someText: '\'hello\' world',
    anObject: {
        'foo': 'fooValue',
        'bar': '10.0'
    } 
}

要成为有效的JSON,它应该如下所示:

{
    "aNumber": 200,    
    "someText": "'hello' world",
    "anObject": {
        "foo": "fooValue",
        "bar": "10.0"
    } 
}

我想将返回的文本更改为有效的JSON对象。我已经使用javascript替换函数将单引号转换为双引号并将转义的单引号转换为单引号,但现在我仍然坚持找出在键值周围添加引号的最佳方法。例如,我如何将foo:“fooValue”更改为“foo”:“fooValue”?是否有正则表达式可以使这很容易?

提前致谢!

5 个答案:

答案 0 :(得分:10)

这个正则表达式可以解决这个问题

$json = preg_replace('/([{,])(\s*)([A-Za-z0-9_\-]+?)\s*:/','$1"$3":',$json);

虽然这是一个PHP!我认为将它转换为JS并不是一个问题。

答案 1 :(得分:8)

我试图在Javascript中使用regEx来解决同样的问题。我有一个为Node.js编写的应用程序来解析传入的JSON,但是想要一个轻松的#34;解析器的版本(参见下面的注释),因为在每个键(名称)周围放置引号是不方便的。这是我的解决方案:

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_ \-\.$]*)允许的姓名字符,以便我放松使用#39;版本JSON解析器。如果您想在名称中允许更多字符(您可以这样做并且仍然具有有效的JSON),则可以使用([^'":]+)来表示除双引号或单引号或冒号之外的任何内容。这仍然会比JSON标准(允许名称中包含单引号)更进一步限制您,但是您将无法使用此方法进行解析。你可以在这里使用这个表达式([^'":]+)获得各种各样的东西,所以要小心。

希望这有帮助。

答案 2 :(得分:3)

编辑 - 回过头来指出,首先,这不是一个可以用正则表达式解决的问题。

将JSON表示法区分为序列化表单和JavaScript对象常量表示法非常重要。

此:

{ x: "hello" }

是一个完全有效的JavaScript值(表达式片段),因此:

var y = { x: "hello" };

给出与以下完全相同的结果:

var y = { "x": "hello" };

换句话说,任何一种情况下“y”的值都是完全相同的。完全,完全相同,这样就不可能分辨出这两个常数中的哪一个用于初始化“y”。

现在,如果您想要做的是将包含JavaScript样式“JSON速记”的字符串转换为有效的JSON,那么唯一要做的就是解析它并使用引号重新构造字符串属性名称。也就是说,您必须编写自己的“宽松”JSON解析器,而不是处理不带引号的标识符作为属性名称,否则找到可以处理这种放松语法的现成解析器。

在你的情况下,看起来一旦你有“放松”的解析器,你就完成了;你不应该需要翻译。值得庆幸的是,您的“无效”JSON响应完全可由JavaScript本身解释,因此,如果您信任数据源(并且这是“if”),您应该能够使用“eval()来评估它”

答案 3 :(得分:0)

需要这样做 - 你已经有了一个有效的 JSON对象。阅读'回合JSON here

如果你需要获得价值,你只需写data.whatever即可。例如:如果你有JSON 对象 data

{
  moo: "foo",
  foo: "bar"
}

所有可能的字段均为moofoo,其用途分别为data.moodata.foo。如果你想使用data作为jQuery参数,你只需按原样传递它:$.load("http://my.site.com/moo", data, function(response){ /* ... */ })

注意:在我提到的最后一个例子中,响应将是一个字符串。要使其成为有效的JSON对象,请使用$.parseJSON(response);方法。

答案 4 :(得分:0)

由于它是一个格式错误的“JSON”,您将无法使用jQuery.getJSON。

您可以使用

jQuery.ajax({
      url : myUrl,
      data : myParams,
      type : "GET",
      success : function(jsontext)
      {
          // jsontext is in text format
          jsontext = jsontext.replace("'", "\"");
          // now convert text to JSON object
          var jsonData = eval('(' + jsontext+ ')');

          // rest of the code
      }
 });