You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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区间)

关键逻辑说明

  1. 最内层括号匹配:用正则\[([^\[\]]+)\]精准匹配不包含其他方括号的最内层括号,避免嵌套结构干扰。
  2. 递归替换:每次找到最内层括号后,递归调用inRange计算括号内表达式的结果,用"true"或"false"替换整个括号。重复此过程直到字符串中无括号。
  3. 布尔值处理:在后续的与/或运算中,直接识别替换后的"true"/"false"字符串,转成布尔值参与运算。
  4. 兼容原有逻辑:替换完成后,原有的范围判断逻辑完全复用,无需额外修改。

测试验证

运行上述代码,所有测试用例都能得到预期结果,包括带多层嵌套方括号的复杂表达式。

内容的提问来源于stack exchange,提问作者DuduYassa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 13:50:42