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

JavaScript双操作数计算器输入的正则验证优化问询

修复双操作数计算器的实时输入验证逻辑

我开发了一款支持+、-、*、/运算的双操作数计算器,原本用内联正则做实时输入验证,但现有逻辑允许2.+.1这类不符合预期的输入。需要调整验证规则,满足:

  • 输入.后必须跟数字(或自动补0)
  • 输入+-*/运算符后必须跟数字(或自动补0)
  • 逐字符实时校验,而非输入完成后统一检查

现有验证代码:

//check if operator is present
if(/[+\-*\/]/.test(display1.textContent)){
    //validate the string each time a new character is added
    if(!/^\d+\.?\d*[+\-*\/]?\d*\.?\d*$/.test(display1.textContent)){
        console.log('invalid')
        return false
    }
//validate the string character by character before operator
} else {
    if(!/^\d+\.?\d*$/.test(display1.textContent)){
        console.log('invalid')
        return false
    } 
}

解决方案:分步校验+前置拦截+自动补全

由于单一正则难以覆盖所有实时输入的边界场景,改用分步校验逻辑,结合前置字符检查和自动补全,既拦截非法输入,又将不规范输入转化为合法格式。

1. 核心验证函数

先实现一个基础的验证函数,确保输入的整体格式合法:

function validateInput(currentDisplayText) {
    if (!currentDisplayText) return true;

    const hasOperator = /[+\-*\/]/.test(currentDisplayText);
    const operatorIndex = currentDisplayText.search(/[+\-*\/]/);

    if (!hasOperator) {
        // 第一个操作数:只能是整数或合法小数(不能有多个小数点,不能仅为小数点)
        return /^\d+(\.\d*)?$/.test(currentDisplayText);
    } else {
        const firstOperand = currentDisplayText.slice(0, operatorIndex);
        const secondOperand = currentDisplayText.slice(operatorIndex + 1);

        // 验证第一个操作数合法性
        if (!/^\d+(\.\d*)?$/.test(firstOperand)) return false;
        // 第二个操作数为空时暂时允许(刚输入运算符还没输数字)
        if (!secondOperand) return true;
        // 验证第二个操作数合法性
        return /^\d+(\.\d*)?$/.test(secondOperand);
    }
}

2. 前置字符拦截

在用户输入新字符前,预判是否允许添加,避免出现.+、+.这类非法序列:

function canAddCharacter(currentText, newChar) {
    // 只允许数字、小数点、运算符
    if (!/[\d\.+\-*\/]/.test(newChar)) return false;

    // 输入小数点的规则:当前操作数不能已有小数点,不能单独作为第一个字符
    if (newChar === '.') {
        const currentSegment = /[+\-*\/]/.test(currentText) 
            ? currentText.slice(currentText.search(/[+\-*\/]/) + 1)
            : currentText;
        if (currentSegment.includes('.') || currentText === '') return false;
    }

    // 输入运算符的规则:不能已有运算符,前面必须是合法操作数
    if (/[+\-*\/]/.test(newChar)) {
        if (/[+\-*\/]/.test(currentText) || !/^\d+(\.\d*)?$/.test(currentText)) {
            return false;
        }
    }

    // 最后做整体验证
    return validateInput(currentText + newChar);
}

3. 自动补全逻辑

将用户的不规范输入转化为合法格式,比如把2.+补成2.0+,把+.1补成+0.1:

function handleUserInput(newChar) {
    let currentText = display1.textContent;

    // 操作数以小数点结尾时,输入运算符前自动补0
    if (/[+\-*\/]/.test(newChar) && currentText.endsWith('.')) {
        currentText += '0';
    }
    // 运算符后直接输入小数点时,自动补0
    if (newChar === '.' && /[+\-*\/]/.test(currentText)) {
        currentText += '0';
    }

    // 验证通过则更新显示,否则拦截
    if (canAddCharacter(currentText, newChar)) {
        display1.textContent = currentText + newChar;
    } else {
        console.log('无效输入');
    }
}

逻辑说明

  • 拆分了单操作数和双操作数阶段的验证,避免单一正则的模糊匹配
  • 前置拦截确保不会出现非法字符序列,比如连续的非数字符号
  • 自动补全让用户的不规范输入自动转化为合法格式,提升体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:50:29