【问题标题】:how to do array split with regex?如何使用正则表达式进行数组拆分?
【发布时间】:2021-12-27 06:20:31
【问题描述】:

我有一个字符串,我需要将其转换为对象数组

const str = "addias (brand|type) sneakers(product) for men(o)"

预期输出

let output = [
 { 
  key:"addias",
  value:["brand","type"]
 },
{ 
  key:"sneakers",
  value:["product"]
 },
{ 
  key:"for men",
  value:[]
 }

]

我试过的代码

function gerateSchema(val) {
       let split = val.split(" ")
       let maps = split.map((i) => {
           let obj = i.split("(")
           let key = obj[0].replaceAll(/\s/g, "")
           let cleanValue = obj[1].replace(/[{()}]/g, "")
           let stripedValues = cleanValue.split("|")

           return {
               key: key,
               value: stripedValues,
           }
       })
       return maps

}
let out = gerateSchema(str)

但是当有一些带有空格的单词时会中断,例如for men

如何使用正则表达式进行拆分

【问题讨论】:

  • 你有没有尝试过?请同时显示
  • 请添加您尝试过的代码。有plenty of questions 匹配() 内的字符串并在| 处拆分。
  • 为什么o没有添加到value数组中?
  • @blurfus 功能添加
  • @adiga 包含或不包含都很好

标签: javascript arrays split splice


【解决方案1】:

一种方法是首先执行正则表达式查找所有以查找原始字符串中的所有键/值组合。然后,迭代该结果并使用单词键和数组值构建一个哈希图。

var str = "addias (brand|type) sneakers(product) for men(o)";
var matches = str.match(/\w+(?: \w+)*\s*\(.*?\)/g, str);
var array = [];
for (var i=0; i < matches.length; ++i) {
    var parts = matches[i].split(/\s*(?=\()/);
    var map = {};
    map["key"] = parts[0];
    map["value"] = parts[1].replace(/^\(|\)$/g, "").split(/\|/);
    array.push(map);
}
console.log(array);

第一个正则表达式匹配每个键/值字符串:

\w+        match a word
(?: \w+)*  followed by a space, and another word, the quantity zero or more times
\s*        optional whitespace
\(         (
.*?        pipe separated value string
\)         )

然后,我们在\s*(?=\() 上拆分每个术语,这是紧接在(...|...) 术语之前的空格。最后,我们拆分管道|上的值字符串,生成值集合。

【讨论】:

  • 如果你为正则表达式添加了 cmets,这对学习者来说会很棒
【解决方案2】:

另一种方法可能是这样。

const str = "addias (brand|type) sneakers(product) for men(o)"
const array = str.split(')').filter(i => i.length).map(i => {
   const item = i.split('(');
   return {
     key: item[0].trim(),
     value: item[1].split('|')
   }
})

console.log(array)

【讨论】:

    【解决方案3】:

    使用exec method 迭代正则表达式找到的模式可能更简单。

    const str = 'addias(brand|type|size|color) sneakers(pro) for men(o)';
    
    // The regex looks for an initial group of letters,
    // then matches the string inside the parentheses
    const regex = /([a-z]+)\(([a-z\|]+)\)/g;
    
    let myArray;
    const arr = [];
    
    while ((myArray = regex.exec(str)) !== null) {
    
      // Destructure out the key and the delimited string
      const [_,  key, ...rest] = myArray;
    
      // `split` on the string found in `rest` first element
      const values = rest[0].split('|');
    
      // Finally push a new object into the output array
      // (removing "o" for whatever reason)
      arr.push({
        key,
        value: values.filter(v => v !== 'o')
      });
    }
    
    console.log(arr);

    【讨论】:

      【解决方案4】:

      regex101.com 的帮助下,导出了以下正则表达式和以下代码。

      ([^\(]+)\(([^\)]*)\) 分解成

      ([^\(]+) - 将 1 个或多个字符捕获到第一个 ( 作为组 1

      \( - 吞下左括号

      ([^\)]*) - 捕获直到下一次出现 ) 的所有内容作为第 2 组

      \) - 吞下正确的括号

      我开始使用 [^|]+ - 解析第 2 组的文本,但实际上使用简单的 split 语句更简单。

          function generateSchema(str) {
              const regex = /([^\(]+)\(([^\)]*)\)/mg;  // captures the 'word (word)' pattern
              let m;
              let output = [];
              let obj = {};
          
              while ((m = regex.exec(str)) !== null) {
          
                  // This is necessary to avoid infinite loops with zero-width matches
                  if (m.index === regex.lastIndex) {
                      regex.lastIndex++;
                  }
              
                  m.forEach((match, groupIndex) => {
                      if (groupIndex === 1) {
                          obj = {};
                          obj.key = match.trim();
                      } else if (groupIndex === 2) {
                          obj.value = match.split('|').map(i=>i.trim());
                          output.push(obj);
                      }
                  });
              }
              return output;
          }
      
          const str = "addidas (brand | type  ) sneakers(product) for men(o)";
          console.log(generateSchema(str));

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多