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

JavaScript编写字符串数值计算功能遇到问题求指导

代码存在的问题
  • 缺少自定义函数getSubstringIndex的定义:代码中处理百分号逻辑时反复调用了该方法,但没有给出实现,运行时会直接抛出未定义错误
  • 未处理特殊运算符映射:你在字符校验规则中允许了x(乘号)和^(幂运算)两个符号,但没有做替换转换,6 x 2、6^2这类表达式直接传给eval会触发语法错误
  • 不支持隐式乘法:类似2(3)的书写方式JS原生不识别,没有做转换处理的话这类表达式运行会报错
  • 未过滤输入中的=符号:如果输入表达式本身包含等号(比如测试用例2 + 2 - 1 = 3 + 2),处理后传入eval的表达式依然存在等号,会触发语法错误
  • 没有异常捕获逻辑:如果表达式存在语法问题,eval会直接抛出错误终止程序,而不是按预期返回空结果
修正后的完整代码
// 补充缺失的getSubstringIndex方法
const getSubstringIndex = (str, substr, occurrence) => {
  let pos = 0;
  for (let i = 0; i < occurrence; i++) {
    pos = str.indexOf(substr, pos + 1);
    if (pos === -1) break;
  }
  return pos;
}

const toCalculate  = (string) => {
  // 先移除输入本身带的等号
  let calculate = "=" + string.toLowerCase().replace(/=/g, "");
  if (
    isFinite(
      calculate.replace(
        /\=|\+|\-|\*|\/|\÷|\%|\(|\)|\,|\ |math.|pow|sqrt|round|floor|ceiling|ceil|pi|π|euler|absolute|abs|exp|logarithm|log|random|rand|rng|x|\^/g,
        ""
      )
    )
  ) {
    calculate = calculate
      .replace(/ /g, "")
      .replace(/÷/g, "/")
      .replace(/x/g, "*") // 新增x转乘号逻辑
      .replace(/\^/g, "**") // 新增^转幂运算逻辑
      // 新增隐式乘法转换:数字/右括号后接左括号时自动补乘号
      .replace(/(\d|\))\(/g, '$1*(')
      .replace(/power|pow/g, "Math.pow")
      .replace(/sqrt|squareroot/g, "Math.sqrt")
      .replace(/round/g, "Math.round")
      .replace(/floor/g, "Math.floor")
      .replace(/ceiling|ceil/g, "Math.ceil")
      .replace(/pi|π/g, "Math.PI")
      .replace(/euler/g, "Math.E")
      .replace(/absolute|abs/g, "Math.abs")
      .replace(/exp/g, "Math.exp")
      .replace(/logarithm|log/g, "Math.log")
      .replace(/random|rand|rng/g, "Math.random()");
    if (calculate.replace(/[^%]/g, "").length > 0) {
      for (let i = 0; i < calculate.replace(/[^%]/g, "").length; i++) {
        while (
          (calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "+" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "-" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "*" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "/" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "(" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == ")" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "," ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "^" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "x" ||
            getSubstringIndex(calculate, "%", i + 1) + 1 == calculate.length) &&
          calculate.replace(/[^%]/g, "").length > 0
        ) {
          for (let j = getSubstringIndex(calculate, "%", i + 1); j > -1; j--) {
            if (
              calculate[j] == "=" ||
              calculate[j] == "+" ||
              calculate[j] == "-" ||
              calculate[j] == "*" ||
              calculate[j] == "/" ||
              calculate[j] == "(" ||
              calculate[j] == ")" ||
              calculate[j] == "," ||
              calculate[j] == "^" ||
              calculate[j] == "x"
            ) {
              calculate =
                calculate.substring(0, j + 1) +
                calculate.substring(j + 1, getSubstringIndex(calculate, "%", i + 1)) / 100 +
                calculate.substring(getSubstringIndex(calculate, "%", i + 1) + 1, calculate.length);
              break;
            }
          }
        }
      }
    }
    calculate = calculate.replace(/=/g, "");
    // 新增异常捕获,避免eval报错阻塞程序运行
    try {
      const res = eval(calculate)
      if (isFinite(res)) return string + ' = ' + res;
    } catch (e) {
      return undefined
    }
  }
};


// 测试用例运行结果
console.log('math 0:', toCalculate('2 ÷ 2 + 1 - 2 + 22')); // 2 ÷ 2 + 1 - 2 + 22 = 22
console.log('math 1:', toCalculate('2 + 2 - 1')); // 2 + 2 - 1 = 3
console.log('math 2:', toCalculate('4 ÷ 2 + 9')); // 4 ÷ 2 + 9 = 11
console.log('math 3:', toCalculate('888 + 88 + 8 + 8 + 8')); // 888 + 88 + 8 + 8 + 8 = 1000
console.log('math 4:', toCalculate('(7+7) * (7 + (1/7))')); // (7+7) * (7 + (1/7)) = 100
console.log('math 5:', toCalculate('2 + 2 - 1 = 3 + 2')); // undefined(表达式本身不合法)
console.log('math 6:', toCalculate('6 - 1 x 0 + 2 ÷ 2')); // 6 - 1 x 0 + 2 ÷ 2 = 7
console.log('math 7:', toCalculate('6^2 ÷ 2(3) + 4')); // 6^2 ÷ 2(3) + 4 = 58
console.log('math 8:', toCalculate('6 - 1 x 0 + 2 ÷ 2')); // 6 - 1 x 0 + 2 ÷ 2 = 7
console.log('math 9:', toCalculate('6 x 2')); // 6 x 2 = 12

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 03:15:07