【问题标题】:string to dictionary in javascript字符串到javascript中的字典
【发布时间】:2021-11-23 12:17:26
【问题描述】:

我有一个字符串要转换成字典,字符串如下所示:

const str = '::student{name="this is the name" age="21" faculty="some faculty"}'

我想将该字符串转换为如下所示的字典:

const dic = {
  "name": "this is the name",
  "age": "21",
  "faculty": "some faculty"
}

所以字符串的格式是::name{parameters...},并且可以有任何参数,不仅是name,faculty,......我如何格式化任何看起来像这样的字符串并将其转换为字典?

还有一种方法可以检查我正在解析的当前字符串是否遵循此结构::name{parameters...},这样我可以在不遵循此结构时抛出错误。

任何帮助将不胜感激!

【问题讨论】:

  • 请edit您的问题表明您对该问题所做的任何研究以及您根据该研究所做的任何尝试。
  • 这感觉像是一个 XY 问题:你最初是如何得到字符串的?有没有办法确保以与大多数语言兼容的格式发送信息/数据(阅读:JSON)?
  • 你定义了要解析的语法吗?例如。字符串中如何包含单引号和/或双引号?

标签: javascript string text-parsing information-extraction


【解决方案1】:

假设值的括号内只有字母数字和空格或空字符串,并且key="value"中的键和值之间没有空格,则可以使用以下正则表达式 然后对其进行迭代以构造您想要的对象。

const str = '::student{name="this is the name" age="21" faculty="some faculty"}'
const matches = str.match(/[\w]+\=\"[\w\s]*(?=")/g)
const result = {}
matches.forEach(match => {
  const [key, value] = match.split('="')
  result[key] = value
})
console.log(result)

正则表达式由以下部分组成:

您可以使用https://regexr.com 来试验您的正则表达式。根据要处理的字符串,您需要优化您的正则表达式。

【讨论】:

    【解决方案2】:

    此示例使用exec 在使用regular expression 的字符串中查找匹配项。

    const str = '::student{name="this is the name" age="21" faculty="some faculty"}';
    
    const regex = /([a-z]+)="([a-z0-9 ?]+)"/g;
    
    let match, output = {};
    
    while (match = regex.exec(str)) {
      output[match[1]] = match[2];
    }
    
    console.log(output);

    【讨论】:

      【解决方案3】:

      如果不存在唯一的模式,很难,但是当模式相同时,可以拆分字符串:

        var str  = '::student{name="this is the name" age="21" faculty="some faculty"}'
      
        console.log(createObj(str));
      
      
        function createObj(myString){
          if(myString.search("::") !== 0 && myString.search("{}") === -1 && myString.search("}") === -1){
            console.log("format error")
            return null;
          }
      
          var a = myString.split("{")[1];
          var c = a.replace('{','').replace('}','');
          if(c.search('= ""') !== -1){
            console.log("format incorrect");
            return null;
          }
      
          var d = c.split('="')
      
          var keyValue = [];
          for(item of d){
            var e = item.split('" ')
            if(e.length === 1){
              keyValue.push(e[0].replace('"',''));
            }else{
              for(item2 of e){
                keyValue.push(item2.replace('"',''));
              }
            }
          }
      
          var myObj = {}
          if(keyValue.length % 2 === 0){
            for(var i = 0; i<keyValue.length; i=i+2){
              myObj[keyValue[i]] = keyValue[i+1]
            }
          }
          return myObj;
        }
      

      【讨论】:

        【解决方案4】:

        您可以使用 2 种模式。第一个匹配字符串格式并在单个捕获组中捕获大括号之间的内容的模式。使用 2 个捕获组获取键值对的第二种模式。

        你可以使用完整的匹配

        ::\w+{([^{}]*)}
        
        • ::\w+ 匹配 :: 和 1+ 个单词字符
        • {匹配开头卷曲
        • ([^{}]*) 捕获第一组,从开始到结束卷曲匹配
        • } 匹配结束卷曲

        Regex demo

        对于您可以使用的键和值

        (\w+)="([^"]+)"
        
        • (\w+) 捕获group 1,匹配1+ word chars
        • =" 字面匹配
        • ([^"]+) 捕获第 2 组,匹配从开头到结尾的双引号
        • "匹配结束双引号

        Regex demo

        const str = '::student{name="this is the name" age="21" faculty="some faculty"}';
        const regexFullMatch = /::\w+{([^{}]*)}/;
        const regexKeyValue = /(\w+)="([^"]+)"/g;
        const m = str.match(regexFullMatch);
        
        if (m) {
          dic = Object.fromEntries(
            Array.from(m[1].matchAll(regexKeyValue), v => [v[1], v[2]])
          );
          console.log(dic)
        }

        【讨论】:

          猜你喜欢
          • 2013-03-17
          • 2011-06-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-11
          • 2019-09-26
          • 2015-10-31
          • 2016-04-08
          相关资源
          最近更新 更多