对于Regex匹配项,忽略N个嵌套括号内的逗号

koaltpgm  于 2023-04-22  发布在  其他
关注(0)|答案(2)|浏览(90)

这是my previous question的直接后续,我得到了下面的Regex;

const matches = text.match(/(?:\([^()]*(?:\([^()]*\)[^()]*)*\)|[^,])+/g);

从这个a,(b, b),c (aaa, (bbb, cccc, ddd)),d我得到

a
(b, b)
c (aaa, (bbb, cccc, ddd))
d

但是当我遇到下面的情况a,(b, b),c (aaa, ((b b), cccc, ddd)),d时,它失败了,其中有3个嵌套的括号,这在剖析Regex如何工作后是合乎逻辑的。
我试图更新它,以考虑另一个级别的括号,我做了以下工作

const matches = text.match(/(?:\([^()]*(?:\([^()]*(?:\([^()]*\)[^()]*)*\)[^()]*)*\)|[^,])+/g)

它工作(online demo),但我不确定它是否是最佳的解决方案。我也不知道它是否会涵盖所有的情况。有人能证实吗?或者可能有一个更好的正则表达式。
我也在寻找一种方法来生成这样的正则表达式给定的括号数.我有它为2和3,但N呢?它会工作,如果我总是重复下面的部分(?:\([^()]*\)[^()]*)*递归?我知道正则表达式不能处理任何数量的嵌套括号,但我不是在寻找这个.我想为一个给定的数字生成正则表达式(使用JS)和使用它.

5n0oy7gb

5n0oy7gb1#

大多数情况下,当你需要跟踪嵌套深度时,单个正则表达式并不是合适的工具。对于这些情况,你可能需要使用编程语言来解析字符串。
对于这个场景,一个简单的解析器可能看起来像这样:

function parseArgString(string) {
  const args = [];
  let argStartIndex = 0;
  let depth = 0;
  
  for (let index = 0; index < string.length; ++index) {
    const char = string[index];
    
    if (char == "(") depth += 1;
    if (char == ")") depth -= 1;
    if (depth < 0) throw new Error('unexpected ")" character');
    
    if (char == "," && !depth) {
      args.push(string.slice(argStartIndex, index).trim());
      argStartIndex = index + 1;
    }
  }
  
  const finalArg = string.slice(argStartIndex).trim();
  if (finalArg.length) args.push(finalArg);
  
  return args;
}

const argString = "a,(b, b),c (aaa, ((b b), cccc, ddd)),d";
console.log(parseArgString(argString));
qij5mzcb

qij5mzcb2#

请参阅this answer下面的JS部分〉* 无递归。* 我只是在那里添加了一个JS片段,以生成所选最大深度的模式。根据您的需要修改了片段(前/后非逗号)。

// JS-Snippet to generate pattern
function generatePattern()
{
  // Set max depth & pattern parts -> build pattern
  let depth = document.getElementById("maxDepth").value;
  let p = ['\\([^)(]*(?:','\\([^)(]*\\)','[^)(]*)*\\)'];
  console.log('(?:' + p[0].repeat(depth) + p[1] + p[2].repeat(depth) + '|[^,])+');
} generatePattern();
Max depth = <input type="text" id="maxDepth" size="1" value="2"> 
<input type="submit" onclick="generatePattern()" value="generate pattern!">

The example you provided在我看来是一个最优的解决方案(覆盖了2层嵌套)。它已经包含了一个unrolled版本,并且很高效。我怀疑是否有很多选项可以进行更多的优化。

相关问题