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

React输入框BODMAS表达式正则验证问题求助

解决React输入框的数学表达式验证与计算问题

用单一正则完全验证符合BODMAS规则的数学表达式(尤其是带嵌套括号的)非常困难——普通正则对嵌套结构的支持有限,你之前的两个正则要么不兼容括号,要么逻辑冗余导致误判。下面给你一套更可靠的方案:

1. 先做括号平衡检查

括号不匹配是最容易排查的错误,先写一个简单函数验证括号成对:

function isBracketsBalanced(str) {
  let balance = 0;
  for (const char of str) {
    if (char === '(') balance++;
    if (char === ')') balance--;
    if (balance < 0) return false; // 右括号提前出现,直接不合法
  }
  return balance === 0; // 最终左右括号数量必须相等
}

2. 结合正则做基础合法性过滤

先过滤掉非法字符,再排除明显的结构错误(比如连续运算符、运算符开头/结尾等):

function isValidExpression(str) {
  const trimmed = str.replace(/\s/g, ''); // 先去掉所有空格,方便后续检查

  // 1. 只允许数字、运算符、括号、小数点
  if (!/^[\d+\-*/().]+$/.test(trimmed)) return false;

  // 2. 验证括号平衡
  if (!isBracketsBalanced(trimmed)) return false;

  // 3. 禁止连续运算符(比如5++3、5*-3)
  if (/([+\-*/]){2,}/.test(trimmed)) return false;

  // 4. 禁止以运算符开头或结尾(括号除外)
  if (/^[+\-*/]|[+\-*/]$/.test(trimmed)) return false;

  // 5. 禁止括号与运算符直接相邻(比如(+5)、5*))
  if (/(\([+\-*/])|([+\-*/]\))/.test(trimmed)) return false;

  // 6. 禁止多个小数点连续或出现在错误位置
  if (/(\.\d*\.)|(^\.)|(\.$)/.test(trimmed)) return false;

  return true;
}

3. 安全计算表达式结果

直接用eval存在安全风险(恶意输入可能执行代码),推荐用new Function替代,或者使用专门的数学库(比如Math.js):

function calculateExpression(expr) {
  if (!isValidExpression(expr)) throw new Error('表达式不合法');
  
  try {
    // 去掉空格后构建计算函数,仅返回表达式结果
    const calc = new Function(`return ${expr.replace(/\s/g, '')}`);
    const result = calc();
    
    if (isNaN(result)) throw new Error('计算结果无效');
    return result;
  } catch (e) {
    throw new Error('计算失败:' + e.message);
  }
}

补充说明

  • 这套方案比单一正则更可靠,能覆盖括号不匹配、非法字符、结构错误等常见问题
  • 如果需要支持负数(比如-5+3),只需调整规则,允许表达式开头为负号,或括号内开头为负号
  • 若要支持更复杂的表达式(比如平方、开方),建议直接使用成熟的数学表达式解析库(如Math.js),避免自己造轮子

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 04:25:09