正则表达式在 JavaScript 中的键周围添加双引号
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/4843746/
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
Regular Expression to add double quotes around keys in JavaScript
提问by Evil E
I am using jQuery's getJSON function to make a request and handle the JSON response. The problem is the response I get back is malformed and I can't change it. The response looks something like this:
我正在使用 jQuery 的 getJSON 函数来发出请求并处理 JSON 响应。问题是我得到的响应格式不正确,我无法更改它。响应如下所示:
{
    aNumber: 200,    
    someText: '\'hello\' world',
    anObject: {
        'foo': 'fooValue',
        'bar': '10.0'
    } 
}
To be valid JSON, it should look like this:
要成为有效的 JSON,它应该如下所示:
{
    "aNumber": 200,    
    "someText": "'hello' world",
    "anObject": {
        "foo": "fooValue",
        "bar": "10.0"
    } 
}
I would like to change the text returned to a valid JSON object. I've used the JavaScript replace function to turn the single quotes into double quotes and the escaped single quotes into single quotes, but now I am stuck on figuring out the best way to add quotes around the key values.
我想将返回的文本更改为有效的 JSON 对象。我已经使用 JavaScript 替换函数将单引号转换为双引号,将转义的单引号转换为单引号,但现在我一直在寻找在键值周围添加引号的最佳方法。
For example, how would I change foo: "fooValue"to "foo":"fooValue"?  Is there a Regular Expression that can make this easy?
例如,我将如何更改foo: "fooValue"为"foo":"fooValue"?是否有正则表达式可以使这变得容易?
Thanks in advance!
提前致谢!
采纳答案by Pointy
edit— came back to point out, first and foremost, that this is not a problem that can be solved with a regular expression.
编辑——回来首先指出,这不是一个可以用正则表达式解决的问题。
It's important to distinguish between JSON notation as a serialized form, and JavaScript object constant notation.
区分作为序列化形式的 JSON 表示法和 JavaScript 对象常量表示法很重要。
This:
这:
{ x: "hello" }
is a perfectly valid JavaScript value (an expression fragment), so that this:
是一个完全有效的 JavaScript 值(表达式片段),因此:
var y = { x: "hello" };
gives you exactly the same result as:
给你完全相同的结果:
var y = { "x": "hello" };
In other words, the value of "y" in either of those cases will be exactly the same. Completely, exactly the same, such that it would not be possible to ever tell which of those two constants was used to initialize "y".
换句话说,在这两种情况下,“y”的值将完全相同。完全一样,完全相同,以至于永远无法分辨这两个常量中的哪一个用于初始化“y”。
Now, if what you want to do is translate a stringcontaining JavaScript style "JSON shorthand" without quotes into valid JSON, the only thing to do is parse it and reconstruct the string with quotes around the property names. That is, you will have to either write your own "relaxed" JSON parser than can cope with unquoted identifiers as property names, or else find an off-the-shelf parser that can handle such relaxed syntax.
现在,如果您想要做的是将包含 JavaScript 样式“JSON 速记”的字符串不带引号转换为有效的 JSON,唯一要做的就是解析它并用属性名称周围的引号重建字符串。也就是说,您将不得不编写自己的“宽松”JSON 解析器来处理不带引号的标识符作为属性名称,或者找到可以处理这种宽松语法的现成解析器。
In your case, it looks like once you have the "relaxed" parser available, you're done; there shouldn't be any need for you to translate back. Thankfully, your "invalid" JSON response is completely interpretable by JavaScript itself, so if you trust the data source (and that's a big"if") you should be able to evaluate it with "eval()".
就您而言,一旦您拥有可用的“轻松”解析器,您就完成了;你应该不需要翻译回来。幸运的是,您的“无效”JSON 响应完全可以由 JavaScript 本身解释,因此如果您信任数据源(这是一个很大的“if”),您应该能够使用“eval()”对其进行评估。
回答by Guy
This regex will do the trick
这个正则表达式可以解决问题
$json = preg_replace('/([{,])(\s*)([A-Za-z0-9_\-]+?)\s*:/','"":',$json);
It's a php though! I assume it's not a problem converting it to JS.
虽然它是一个 php!我认为将其转换为 JS 不是问题。
回答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 $1is either {or ,depending on whether the object was embedded in another object.  \"adds a double quote.  $2is 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 have valid JSON), you could instead use([^'":]+)to mean anything other than double or single quotes or a colon. This would still limit you further than the JSON standard (which allows single quotes in the name) but then you wouldn't be able to parse using this method. You can have all sorts of stuff in here with this expression([^'":]+), so be careful.
- 我还没有测试过这种方法的速度,但从我通过阅读其中一些条目收集的信息来看,使用正则表达式比使用正则表达式要快 eval()
- 对于我的应用程序,我限制了([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*)我的“宽松”版本 JSON 解析器允许使用的名称字符。如果您想在名称中允许更多字符(您可以这样做并且仍然具有有效的 JSON),您可以改为使用([^'":]+)除双引号或单引号或冒号以外的任何内容。这仍然会比 JSON 标准(允许在名称中使用单引号)进一步限制您,但是您将无法使用此方法进行解析。你可以用这个表达式在这里有各种各样的东西([^'":]+),所以要小心。
Hope this helps.
希望这可以帮助。
回答by shybovycha
UPD 2020:the object you have is a valid javascript object, but not 100% valid JSON.
UPD 2020:您拥有的对象是有效的javascript 对象,但不是 100% 有效的JSON。
An easy way to convert it to valid JSON is to utilize the features JavaScript provides you with, JSON.stringify:
将其转换为有效 JSON 的一种简单方法是利用 JavaScript 为您提供的功能JSON.stringify:
JSON.stringify(object)
You can run this in your browser's JS console.
您可以在浏览器的 JS 控制台中运行它。
To get it formatted (aka "pretty-printed"), you can pass two arguments to this function - the replacer(a function which allows you to filter out some of the properties of your object; just pass a nullif you don't care) and space(either the numberof spaces or a stringwhich will be placed before each key-value pair of your object' string representation):
要对其进行格式化(又名“漂亮打印”),您可以向此函数传递两个参数 -替换器(一个允许您过滤掉对象的某些属性的函数;null如果您不关心,只需传递 a )和空间(或者数目的空格或一个串,将每个键-值对的对象字符串表示)的前被放置:
JSON.stringify(object, null, 4)
In your case, this call
在你的情况下,这个电话
JSON.stringify({
    aNumber: 200,    
    someText: '\'hello\' world',
    anObject: {
        'foo': 'fooValue',
        'bar': '10.0'
    } 
}, null, 4)
will give you
会给你
{
    "aNumber": 200,
    "someText": "'hello' world",
    "anObject": {
        "foo": "fooValue",
        "bar": "10.0"
    }
}
回答by Manish Mulani
Since it's a malformed "JSON", you will not be able to use jQuery.getJSON.
由于它是格式错误的“JSON”,您将无法使用 jQuery.getJSON。
You can use
您可以使用
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
      }
 });

