如何将字符串中的重复键替换为数组,如javascript中的正则表达式

如何将字符串中的重复键替换为数组,如javascript中的正则表达式,javascript,regex,Javascript,Regex,我从第三方收到了这个字符串 {messages:{\n something:'val'}\n messages:{\n something:'val2'}\n}\n 我想通过正则表达式将其更改为下面的字符串 {messages:[{\n something:'val'}\n,{\n something:'val2'}\n]}\n 简单版本 {messages:{something:'val'}messages:{something:'val2'}} 到 {messages:[{something

我从第三方收到了这个字符串

{messages:{\n something:'val'}\n messages:{\n something:'val2'}\n}\n

我想通过正则表达式将其更改为下面的字符串

{messages:[{\n something:'val'}\n,{\n something:'val2'}\n]}\n

简单版本
{messages:{something:'val'}messages:{something:'val2'}}

{messages:[{something:'val'},{something:'val2'}]}

更新 这是我字符串的一部分,因此在like之前和之后还有一些属性

{prop1:'val1',{prop2:'val2',消息:{something:'val'}消息:{something:'val2'}}}

期望

{prop1:'val1',{prop2:'val2',消息:[{something:'val'},{something:'val2'}]}

更新 我真正的弦是


id:“55b3a5c5-16e7-4ae6-91bc-7f08fb152dde-ee1dc704\”\nlang:“en\”会话id:“6b1f9ba2-7c79-47bc-aadb-2c600b111836\”ntimestamp:“2019-09-04T17:13:43.374Z\”\n结果来源:“\n代理\”\n已解决的查询:“\n欢迎”\n操作:“\n分数:1.0\n关键字段值:{\n{\n string\u value:\'welcome\'\n}\n}\n fields{\n key:\'default\'\n value{\n string\u value:\'您好,您呼叫了公寓机器人。您的虚拟礼宾部。我今天能为您做些什么?\'\n}\n}\n}\n元数据{\n intent\u id:\'040b9e41-d20e-4da8-9fff-D2C1F5812E\'\n webhook\u响应时间:4992\n意图\u名称:\“默认欢迎意图-自定义\”\n webhook\u使用:\“真\”\n webhook\u用于插槽填充\n使用:\“假\”\n是回退\u意图:\“假\”\n实现{\n语音:\“您好,您呼叫了公寓机器人。您的虚拟礼宾员。今天我能为您做些什么?\”\n消息{\n lang en:“恩”\n type{\n number\u value:0.0\n}\n speech{\n string\u value:\'Text 1\'\n}\n messages{\n lang:\'en\'\n type{\n number\u value:0.0\n}\n speech{\n string\u value:\'Text 2\'\n}\n}\n}\n状态{\n代码:200\n错误类型:\'success\\ n}\n


p、 s在我的真实字符串中,每个消息对象内部都有更多的消息,为了简单起见,我在这里删除了它们。

这里是一个可能的解决方案:

var messages=“{prop1:'val1',{prop2:'val2',messages:{something:'val'}messages:{something:'val2'}}”;
var结果=[];
messages.split('messages:').map(
消息=>{
console.log(消息)
const val=message.match(/{\s*(.*):'(.*)\s*}/)
if(val){
result.push({[val[1]]:val[2]})
}
}
)
log({messages:result})
我所做的是:

  • 使用regex并将字符串转换为JSON字符串格式 (
    str1
    在代码中)
  • 再次使用正则表达式将字符串拆分为单独的对象,如字符串(
    str2
    ,在我的代码中)。在这里,我可以只解析整个字符串(str1),但这样做会丢失重复的键对象,因此我单独解析字符串(str2)
  • 将每个字符串解析为对象(
    arr
    在我的代码中)
  • 将这些对象添加到具有数组值的新对象中,如果对象具有重复的键,只需将该值推送到现有键中即可

  • 消息中获取所有组1:({[^}]+})
    ,用逗号连接它们,然后用
    “{messages:[“+group1WithCommas+”]}”
    ?@Sweeper创建新字符串。我刚才看到了这个。第三方仍然在设计自己的数据格式,这让我一直感到惊讶。@Sweeper看起来不错,但我真的不擅长regex@Sweeper有趣的是,第三方是谷歌dialogflow@Sweeper你是说用正则表达式进行分组,剩下的用js进行分组?或者所有的事情都可以用正则表达式完成?对不起,在我写回复的时候你更新了问题。不用担心,我看到了你的答案,在我更新了我的问题之后;)谢谢,我们可以去掉
    一些东西吗
    ,因为在我的真实字符串中,我有一个复杂的对象,但并不总是这样,我唯一需要硬编码的是
    消息
    请查看我的真实字符串,我不认为拆分是一个选项。你让我感到厌烦。请正确提问,不要每5分钟改变一次。。所以,有时候我觉得为一个不关心他人,只想免费快速回应问题的人工作。。。抱歉。感谢您分享您的解决方案,它似乎太局限于我的简单示例,我不确定是否可以在我的复杂字符串上使用它
    let str = "{ messages: {something:'val'}  messages: { something:'val2' } }";
    let reg = /[:}{a-zA-Z1-9]{1,}/g;
    
    let str1 = str.replace(/\s/,'').match(reg).map(str => {
      if(/\w/.test(str)){
        let s = str.match(/\w{1,}/).toString();
        return str.replace(s, '"'+ s +'"');
      }
      else  
        return str;
    });
    
    let str2 = str1.toString().replace(/,{/g,'{').replace(/,}/g,'}').replace(/:,/g,':').replace(/{,/g,'{');
    
    let arr = str2.replace('},','}},{').split(',').map(str => JSON.parse(str));
    
    let obj = {};
    
    for(o of arr){
      Object.keys(o).forEach(key => {
        if(!obj.hasOwnProperty(key))
          obj[key] = [o[key]];
        else
          obj[key].push(o[key]);
      });
    }
    
    console.log(JSON.stringify(obj));