首页 > 解决方案 > 在 JavaScript 中捕获嵌套表达式

问题描述

我正在尝试解析诸如(1 < 2 ? foo : bar)JavaScript 中的表达式(类似于简写 if-then-else 表达式)以提取条件部分(1 < 2)、然后部分(foo)和其他部分(bar)。我正在使用适用于简单表达式的正则表达式,但是当我尝试解析嵌套表达式时,正则表达式失败。

正则表达式:/\((.*)\?([^:]*)(:.*)?\)/

简单的例子:

/\((.*)\?([^:]*)(:.*)?\)/.exec('dsa dsadsa dsa(1 < 2 ? foo : bar) dsa dsa dsa')

0: "(1 < 2 ? foo : bar)"
1: "1 < 2 "
2: " foo "
3: ": bar"

嵌套示例 ( (H < 12 ? (m > 30 ? foo : bar) : baz))):

/\((.*)\?([^:]*)(:.*)?\)/.exec('dsa dsadsa dsa(H < 12 ? (m > 30 ? foo : bar) : baz)) dsa dsa dsa')
0: "(H < 12 ? (m > 30 ? foo : bar) : baz))"
1: "H < 12 ? (m > 30 "
2: " foo "
3: ": bar) : baz)"

作为嵌套示例的结果,我真正想要的是

1: "H < 12"
2: "(m > 30 ? foo : bar)"
3: ": baz"

但正则表达式不尊重表达式的嵌套结构。有没有办法做到这一点?

标签: javascriptregex

解决方案


我认为没有办法使用正则表达式一次性完成所有操作,但您可以从最嵌套的匹配开始,然后逐层向外工作。

我已将正则表达式更改为仅匹配嵌套最多的匹配项,然后,一旦读取了它们的数据,我就str从读。

let str = 'dsa dsadsa dsa(H < 12 ? (m > 30 ? foo : bar) : baz)) dsa dsa dsa';
const regex = /\(([^?]+)\?([^:()]*):([^()]+)?\)/;

const list = [];
let matches = regex.exec(str);
let loopLimit = 1000;
while (matches) {
  if (loopLimit-- <= 0) throw 'loopLimit exhausted';
  str = str.replace(matches[0], `~list[${list.length}]~`);
  list.push(matches);
  
  matches = regex.exec(str);
}

console.log(list);
for (let item of list) {
  console.log(item[1]);
}


推荐阅读