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

Posted

技术标签:

【中文标题】如何使用正则表达式进行数组拆分?【英文标题】: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 包含或不包含都很好 【参考方案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));

【讨论】:

以上是关于如何使用正则表达式进行数组拆分?的主要内容,如果未能解决你的问题,请参考以下文章

使用正则表达式将字段拆分为数组的 Bash 脚本用于多字符分隔符

正则表达式(preg_split):如何根据分隔符进行拆分,不包括一对引号中包含的分隔符?

使用php preg_match(正则表达式)将camelCase单词拆分为单词

正则表达式拆分 CSV

如何使用正则表达式拆分字符串而不消耗拆分器部分?

Python正则表达式拆分但保留某些字符以进行拆分