要让scanner.hasnext(pattern)严格匹配整个输入,必须用^和$锚定正则表达式;否则它默认查找子串匹配。例如"^\d+$"确保纯数字,配合next()可安全读取已验证输入。

<p>要让 <code>Scanner.hasNext(Pattern)</code> 只在用户输入**完全匹配**指定正则模式时才返回 <code>true</code>,关键在于:正则表达式必须**隐式或显式锚定到整个输入串的开头和结尾**。否则,<code>hasNext(Pattern)</code> 默认只做“查找匹配”(类似 <code>Matcher.find()</code>),只要输入中**任意子串**符合模式就会返回 <code>true</code>,这通常不是你想要的。</p>
<h3>为什么直接写 <code>"\d+"</code> 不行?</h3>
<p><code>Scanner.hasNext("\d+")</code> 会把 <code>"abc123def"</code> 或 <code>"42 extra"</code> 都判为 <code>true</code> —— 因为它只要找到连续数字就满足。而你通常希望用户输入的是“纯数字”,不能带空格、字母等多余字符。</p>
<h3>正确做法:用 <code>^</code> 和 <code>$</code> 锚定整个输入</h3>
<p>强制要求输入从头到尾都符合模式:</p>
- 匹配纯整数:
scanner.hasNext("^\d+$") - 匹配带可选正负号的整数:
scanner.hasNext("^-?\d+$") - 匹配小数(如
3.14、-0.5):scanner.hasNext("^-?\d+\.\d+$") - 匹配邮箱(简化版):
scanner.hasNext("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$")
配合 next() 安全读取已确认匹配的内容
先用 hasNext(Pattern) 判断,再用 next() 拿值,避免因格式错误导致异常:
<code>Scanner scanner = new Scanner(System.in);
Pattern intPattern = Pattern.compile("^-?\d+$");
System.out.print("请输入一个整数: ");
while (!scanner.hasNext(intPattern)) {
System.out.print("格式错误,请重新输入整数: ");
scanner.next(); // 跳过非法输入,防止死循环
}
String validInput = scanner.next(); // 此时必为纯数字字符串
int value = Integer.parseInt(validInput); // 安全转换
</code>
注意边界情况与增强健壮性
-
hasNext(Pattern)不会自动跳过空白;如果用户输完按空格再回车,"123 "(末尾有空格)不匹配"^\d+$"。可改用"^\s*-?\d+\s*$"并在next()后调用.trim() - 若需忽略大小写(如邮箱),构造
Pattern时加Pattern.CASE_INSENSITIVE标志 - 避免在循环中反复编译正则:把
Pattern.compile(...)提到循环外复用










