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

计算器输入验证器正则修复:支持数字开头负号

修复计算器输入验证器的负号匹配问题

看起来你的输入验证逻辑存在几个关键问题,尤其是负号的处理逻辑完全颠倒了(现在是只要有负号就直接返回true,这会放过很多非法情况),还有连续运算符的判断没有区分合法的负号场景。下面是针对你的需求的修复方案,包括修正后的代码和正则说明:

核心问题分析

  • 错误的负号判断:你当前的代码只要发现负号就返回true,这意味着像(23+*23-)这种明显非法的输入也会被判定为合法。
  • 连续运算符误判:原正则[-*+^\/]{2}会把合法的场景(比如23*-43中的*-)当成非法连续运算符,因为它没有区分“运算符后跟负号(作为数字前缀)”和“真正的连续运算符”。
  • 无效的小数点判断:input.contains(".")就返回true完全不合理,因为包含小数点的输入可能是非法的(比如..3或3..)。

修复后的验证方法

下面是修正后的validateInput方法,针对合法负号的场景(开头、左括号后、运算符后)做了正确的判断,同时排除所有非法情况:

public boolean validateInput(String input) {
    // 处理空输入或纯空格输入
    if (input == null || input.trim().isEmpty()) {
        return false;
    }
    input = input.trim();

    // 1. 检查括号是否成对匹配
    int openParenCount = input.replaceAll("[^(]", "").length();
    int closeParenCount = input.replaceAll("[^)]", "").length();
    if (openParenCount != closeParenCount) {
        return false;
    }

    // 2. 检查是否包含非法字符(仅允许数字、+-*/^()和小数点)
    Pattern illegalCharPattern = Pattern.compile("[^\\d+\\-*/^().]");
    Matcher illegalCharMatcher = illegalCharPattern.matcher(input);
    if (illegalCharMatcher.find()) {
        return false;
    }

    // 3. 检查开头合法性:不能以+*/^开头(负号开头合法)
    if ("+*/^".indexOf(input.charAt(0)) != -1) {
        return false;
    }

    // 4. 检查结尾合法性:不能以运算符或左括号结尾
    char lastChar = input.charAt(input.length() - 1);
    if ("+-*/^(".indexOf(lastChar) != -1) {
        return false;
    }

    // 5. 检查左括号后是否跟非法内容(不能直接跟+*/^)
    Pattern invalidAfterParen = Pattern.compile("\\([+*\\/^]");
    Matcher afterParenMatcher = invalidAfterParen.matcher(input);
    if (afterParenMatcher.find()) {
        return false;
    }

    // 6. 检查右括号前是否跟非法内容(不能是运算符或左括号)
    Pattern invalidBeforeParen = Pattern.compile("[+\\-*\\/^()]\\)");
    Matcher beforeParenMatcher = invalidBeforeParen.matcher(input);
    if (beforeParenMatcher.find()) {
        return false;
    }

    // 7. 检查非法的连续符号:
    // - 两个普通运算符连续(比如++、+*)
    // - 负号后跟普通运算符(比如-+、-*)
    // - 连续负号(比如--)
    Pattern invalidConsecutive = Pattern.compile("([+*\\/^])[+*\\/^]|\\-[+*\\/^]|\\-\\-");
    Matcher consecutiveMatcher = invalidConsecutive.matcher(input);
    if (consecutiveMatcher.find()) {
        return false;
    }

    // 8. 检查小数点合法性:不能有多个小数点在同一个数字段
    Pattern invalidDot = Pattern.compile("\\.\\d*\\.");
    Matcher dotMatcher = invalidDot.matcher(input);
    if (dotMatcher.find()) {
        return false;
    }

    return true;
}

关键正则说明

针对负号的核心判断在invalidConsecutive正则中:

  • ([+*\/^])[+*\/^]:匹配两个普通运算符连续的情况(比如+*、^/),这些是非法的。
  • \\-[+*\/^]:匹配负号后跟普通运算符的情况(比如-+、-*),这些是非法的,因为负号后面应该跟数字或左括号。
  • \\-\\-:匹配连续负号的情况(比如--),这种情况没有实际的数字作为前缀,属于非法。

而合法的负号场景(比如-34、(-34)、23*-43)都会被自动允许,因为它们不符合上述非法正则的匹配规则。

测试用例验证

  • 合法输入:(-34+56)、(23*-43)、-123+45、3^-2 → 返回true
  • 非法输入:(23+*23-)、++34、(3+)、--3、*34 → 返回false

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:28:41