如何用JavaScript正则匹配所有if语句及其条件?
提取带嵌套/多行括号的if语句条件
需要从代码中提取所有if语句及其完整条件(包括嵌套括号、跨多行的情况),示例输入:
if (bla === 3) { } if ((((ol === 1 || (true))))) {} if ((1 === 4) (this === 9)) {}
期望输出:
if (bla === 3)
if ((((ol === 1 || (true)))))
if ((1 === 4) (this === 9))
常规正则无法处理嵌套括号(会返回不完整的未闭合括号匹配),或错误匹配到{}及后续冗余代码。
方法1:支持递归/平衡组的正则引擎(PCRE、Python regex库等)
普通正则不支持嵌套结构,需使用递归匹配处理括号平衡,同时通过正向预查避免匹配冗余内容。
正则表达式
^\s*if\s*(\((?:[^()]|(?1))*\))(?=\s*{)
必备修饰符
m(多行模式):让^匹配每行开头,兼容带缩进的if语句s(DOTALL模式):允许匹配换行符,支持跨多行的条件内容
匹配逻辑
^\s*:匹配行首空白字符(处理代码缩进)if\s*:匹配if关键字及后续空白(\((?:[^()]|(?1))*\)):递归匹配括号内内容,确保括号平衡:\(:匹配左括号(?:[^()]|(?1))*:匹配任意非括号字符,或递归引用当前捕获组模式(处理嵌套括号)\):匹配对应的右括号
(?=\s*{):正向预查,确保匹配结束后紧跟空白和{,避免包含冗余代码
方法2:JavaScript原生实现(无递归正则支持)
JavaScript原生正则不支持递归,可通过括号计数手动解析:
function extractIfConditions(code) { const results = []; let currentIf = ''; let bracketCount = 0; let inIf = false; for (const line of code.split('\n')) { if (!inIf) { const ifMatch = line.match(/^\s*if\s*\(/); if (ifMatch) { inIf = true; currentIf = line.slice(ifMatch.index); // 统计当前行的括号数量差 bracketCount = (currentIf.match(/\(/g) || []).length - (currentIf.match(/\)/g) || []).length; // 若当前行已完成括号闭合 if (bracketCount === 0) { currentIf = currentIf.replace(/\s*{.*$/, '').trim(); results.push(currentIf); inIf = false; } } } else { currentIf += '\n' + line; // 更新括号计数 bracketCount += (line.match(/\(/g) || []).length - (line.match(/\)/g) || []).length; // 括号完全闭合时结束匹配 if (bracketCount === 0) { currentIf = currentIf.replace(/\s*{.*$/, '').trim(); results.push(currentIf); inIf = false; currentIf = ''; } } } return results; } // 测试示例 const code = `if (bla === 3) { } if ((((ol === 1 || (true))))) {} if ((1 === 4) (this === 9)) {}`; console.log(extractIfConditions(code));
执行后会返回期望的三个if语句结果。
内容的提问来源于stack exchange,提问作者XpomIX
相关产品推荐
相关产品推荐

