计算器输入验证器正则修复:支持数字开头负号
修复计算器输入验证器的负号匹配问题
看起来你的输入验证逻辑存在几个关键问题,尤其是负号的处理逻辑完全颠倒了(现在是只要有负号就直接返回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
相关产品推荐
相关产品推荐

