在JavaScript中,正则表达式添加双引号来包含值和键。

7
我需要一个有效的JSON格式来请求ES。我有一个字符串,如下:
{ 
time:  { 
          from:now-60d,
          mode:quick,
          to:now } 
}

但是当我尝试使用JSON.parse时,我遇到了一个错误,因为我的字符串应该像这样:

 { 
time:  { 
          "from":"now-60d",
          "mode":"quick",
          "to":"now" } 
}

我的问题是,有没有办法在我的字符串中添加双引号来包括键和值?
谢谢。

1
为什么不先生成一个对象,然后将数据渲染成真正的 JSON 字符串呢? - Nina Scholz
问题在于字符串是由Kibana自动生成的(我通过URL恢复它)。 - Idriss Benbassou
4个回答

15

也许你可以使用:

str.replace(/([a-zA-Z0-9-]+):([a-zA-Z0-9-]+)/g, "\"$1\":\"$2\"");

这里是

正则表达式演示


注意

在字符组[a-zA-Z0-9-]中,我使用了字母数字和一个-,你可能需要其他的字符组,所以你可以使用另外一个。


1
不客气。@IdrissBenbassou - 如果这对你有帮助(显然是的;),你应该点赞(答案左侧的向上箭头),这会让其他遇到类似问题的人更容易找到好的答案。 - SamWhan
我该如何在Bash中实现这个? - Tanzeel
1
嗨@Tanzeel,抱歉我不熟悉bash,但您可以提出问题,我相信您很快就会得到答案 :) - Youcef LAIDANI
运行良好,你应该在你的正则表达式中也加入"_"字符。 - millenion
嗨 @YCF_L,如果值中有逗号,这种方式似乎不起作用。您有什么处理方法吗? - Sri Bharath
显示剩余4条评论

4

这个函数将添加引号并移除对象末尾的任何额外逗号。

function normalizeJson(str){return str.replace(/"?([\w_\- ]+)"?\s*?:\s*?"?(.*?)"?\s*?([,}\]])/gsi, (str, index, item, end) => '"'+index.replace(/"/gsi, '').trim()+'":"'+item.replace(/"/gsi, '').trim()+'"'+end).replace(/,\s*?([}\]])/gsi, '$1');}

编辑:

这个函数支持JSON数组。

同时,它会将单引号转换为双引号,并且留意不在数字和布尔值上添加引号。

function normalizeJson(str){
    return str.replace(/[\s\n\r\t]/gs, '').replace(/,([}\]])/gs, '$1')
    .replace(/([,{\[]|)(?:("|'|)([\w_\- ]+)\2:|)("|'|)(.*?)\4([,}\]])/gs, (str, start, q1, index, q2, item, end) => {
        item = item.replace(/"/gsi, '').trim();
        if(index){index = '"'+index.replace(/"/gsi, '').trim()+'"';}
        if(!item.match(/^[0-9]+(\.[0-9]+|)$/) && !['true','false'].includes(item)){item = '"'+item+'"';}
        if(index){return start+index+':'+item+end;}
        return start+item+end;
    });
}

我还使用了safe-regex npm模块来测试正则表达式。


很不幸,第一个解决方案在值中弄乱了逗号,例如=> {test : "1,000.00"},规范化后会删除值中的逗号。而第二个解决方案则去掉了值中的空格{test: "2020/11/19 16:11:46" } - Dinesh

2

未加引号的JSON并不是真正的有效JSON,它只是JavaScript。如果您信任这个字符串的来源:

var obj = eval("'({ 
time:  { 
      from:now-60d,
      mode:quick,
      to:now } 
 })'");

不建议对来自不可信来源的字符串进行此操作,因为这可能会造成安全风险。

考虑到您正在从Kibana获取数据,这些数据可能是可信的,因此eval该字符串应该没问题。

另一种选项是使用正则表达式,也许其他答案已经详细说明了。或者,您可能需要修复Kibana导出文件,以提供一个正确/有效的JSON字符串。


谢谢你的回答。 - Idriss Benbassou

1

你好,Idriss

如果你想在所有有效的键名和值周围加上引号,那么可以看一下这个表达式。YCF_L的回答完美地满足了你的需求。但是无论如何,这里还是提供一下。

{(?=[a-z])|[a-z](?=:)|:(?=[a-z])|[a-z](?=,)|,(?=[a-z])|[a-z](?=})
str.replace(/{(?=[a-z])|[a-z](?=:)|:(?=[a-z])|[a-z](?=,)|,(?=[a-z])|[a-z](?
=})/igm, $&");

谢谢你的回答。 - Idriss Benbassou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接