JavaScript支持嵌套括号的数值范围校验递归函数实现问题
实现支持嵌套方括号的数值范围校验功能
问题说明
需要给现有的inRange函数添加嵌套方括号支持,让它能解析带[...]的表达式,比如inRange(75, "0...100 & [70...80, 0...100] & 30...50")应返回false——因为75满足0...100和[70...80, 0...100],但不满足30...50,最终逻辑与运算结果为false。
原函数已经能处理无括号的&(与)、,(或)和范围表达式,但无法识别括号优先级。之前尝试的递归解析括号位置思路方向正确,但需要结合表达式求值替换括号内容。
解决方案
核心思路是从最内层括号开始,递归将括号内的表达式计算为布尔值,替换整个括号部分,直到字符串中没有括号,再用原逻辑处理最终的表达式,以此解决括号优先级问题。
修改后的完整代码
const andRegex = /[ ]*[&][ ]*/gim const orRegex = /[ ]*[,][ ]*/gim const betweenRegex = /[ ]*[...][ ]*/gim // 匹配最内层方括号:不包含其他方括号的[...] const innerBracketRegex = /\[([^\[\]]+)\]/; function inRange(value, rngStr) { // 先处理所有嵌套的方括号:从最内层开始替换为布尔值 let processedStr = rngStr; while (innerBracketRegex.test(processedStr)) { // 替换每一个最内层括号 processedStr = processedStr.replace(innerBracketRegex, (match, group) => { // 递归计算括号内的表达式结果 return inRange(value, group).toString(); }); } // 处理替换后的字符串,包含布尔值和范围表达式 let orArray = splitWithCondition(processedStr, orRegex); let orResult = false; for (let j = 0; j < orArray.length; j++) { let andArray = splitWithCondition(orArray[j], andRegex); let andResult = true; for (let i = 0; i < andArray.length; i++) { let segment = andArray[i].trim(); // 如果是布尔值字符串,直接转成布尔值参与运算 if (segment === 'true' || segment === 'false') { andResult = andResult && (segment === 'true'); } else { // 复用原有的范围判断逻辑 let betweenArray = splitWithCondition(segment, betweenRegex); let isBigger = betweenArray[0] ? value >= +betweenArray[0] : true; let isSmaller = betweenArray[1] ? value <= +betweenArray[1] : true; andResult = andResult && isBigger && isSmaller; } } orResult = orResult || andResult; } return orResult; } function splitWithCondition(text, splitter, condition = value => value) { let arr = text.split(splitter); let result = []; for (let i = 0; i < arr.length; i++) { if (condition(arr[i])) { result.push(arr[i]); } } return result; } // 测试用例 console.log(inRange(100, "...100")); // true console.log(inRange(100, "0...")); // true console.log(inRange(100, "0...100")); // true console.log(inRange(100, "0...100, 150...200")); // true console.log(inRange(100, "0...100 & 70...120")); // true console.log(inRange(75, "0...100 & 70...80, 0...100 & 30...50")); // true console.log(inRange(75, "0...100 & [70...80, 0...100] & 30...50")); // false console.log(inRange(50, "[[0...40, 60...100], 30...70] & 40...60")); // true(50满足[30...70],且在40...60区间)
关键逻辑说明
- 最内层括号匹配:用正则
\[([^\[\]]+)\]精准匹配不包含其他方括号的最内层括号,避免嵌套结构干扰。 - 递归替换:每次找到最内层括号后,递归调用
inRange计算括号内表达式的结果,用"true"或"false"替换整个括号。重复此过程直到字符串中无括号。 - 布尔值处理:在后续的与/或运算中,直接识别替换后的
"true"/"false"字符串,转成布尔值参与运算。 - 兼容原有逻辑:替换完成后,原有的范围判断逻辑完全复用,无需额外修改。
测试验证
运行上述代码,所有测试用例都能得到预期结果,包括带多层嵌套方括号的复杂表达式。
内容的提问来源于stack exchange,提问作者DuduYassa
相关产品推荐
相关产品推荐

