我正在尝试解析JavaScript中的(1 < 2 ? foo : bar)
等表达式(类似于简写if-then-else表达式)以提取条件部分(1 < 2
),当时部分(foo
)和else部分(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"
但正则表达式不尊重表达式的嵌套结构。有没有办法实现这一目标?
我认为没有办法使用正则表达式一次性完成所有操作,但您可以从嵌套最多的匹配项开始,然后分层向外工作。
我已经将正则表达式更改为仅匹配嵌套最多的匹配项,然后,一旦读取了它们的数据,我就会从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]);
}
我想你可以试试
((.*?)?((?.*)?)?:((?.*)?)?)
演示