使用java.util.Scanner验证输入 [英] Validating input using java.util.Scanner
问题描述
我正在使用 java.util.Scanner
从 System.in
获取用户输入。我需要验证以下内容的输入:
I'm taking user input from System.in
using a java.util.Scanner
. I need to validate the input for things like:
- 必须是非负数
- 必须是按字母顺序排列的字母
- ...等
什么是最好的方法这样做?
What's the best way to do this?
推荐答案
概述Scanner.hasNextXXX
方法
java.util.Scanner
有许多 hasNextXXX
方法,可用于验证输入。以下是所有这些内容的简要概述:
Overview of Scanner.hasNextXXX
methods
java.util.Scanner
has many hasNextXXX
methods that can be used to validate input. Here's a brief overview of all of them:
-
hasNext()
- 是否有任何令牌? -
hasNextLine()
- 是否有另一行输入? - 对于Java原语
-
hasNextInt()
- 它是否有可以解析为int
? - 也可以
hasNextDouble()
,hasNextFloat()
,hasNextByte()
,hasNextShort()
,hasNextLong()
,以及hasNextBoolean ()
- 作为奖励,还有
hasNextBigInteger()
和hasNextBigDecimal()
- 整数类型也有重载来指定基数(例如十六进制)
hasNext()
- does it have any token at all?hasNextLine()
- does it have another line of input?- For Java primitives
hasNextInt()
- does it have a token that can be parsed into anint
?- Also available are
hasNextDouble()
,hasNextFloat()
,hasNextByte()
,hasNextShort()
,hasNextLong()
, andhasNextBoolean()
- As bonus, there's also
hasNextBigInteger()
andhasNextBigDecimal()
- The integral types also has overloads to specify radix (for e.g. hexadecimal)
hasNext(String pattern)
hasNext(Pattern pattern)
is thePattern.compile
overload
扫描仪
能够提供更多功能,因为它是基于正则表达式的。一个重要的特征是useDelimiter(字符串模式)
,可让您定义模式分隔您的标记的内容。还有find
和跳过> c $ c> 忽略分隔符的方法。
Scanner
is capable of more, enabled by the fact that it's regex-based. One important feature isuseDelimiter(String pattern)
, which lets you define what pattern separates your tokens. There are alsofind
andskip
methods that ignores delimiters.以下讨论将使正则表达式尽可能简单,因此重点仍然是
扫描程序
。The following discussion will keep the regex as simple as possible, so the focus remains on
Scanner
.以下是使用
的简单示例hasNextInt()
从输入验证正int
。Here's a simple example of using
hasNextInt()
to validate positiveint
from the input.Scanner sc = new Scanner(System.in); int number; do { System.out.println("Please enter a positive number!"); while (!sc.hasNextInt()) { System.out.println("That's not a number!"); sc.next(); // this is important! } number = sc.nextInt(); } while (number <= 0); System.out.println("Thank you! Got " + number);
这是一个示例会话:
请输入正数!
five
这不是号码!
-3
请输入正数!
5
谢谢!得到5Please enter a positive number!
five
That's not a number!
-3
Please enter a positive number!
5
Thank you! Got 5注意多么容易
Scanner.hasNextInt()使用code>比较详细
try / catch
Integer.parseInt
/NumberFormatException
组合。按合同,扫描器
保证如果hasNextInt()
,那么nextInt()
将和平地给你int
,不会抛出任何NumberFormatException
/InputMismatchException
/NoSuchElementException
。Note how much easier
Scanner.hasNextInt()
is to use compared to the more verbosetry/catch
Integer.parseInt
/NumberFormatException
combo. By contract, aScanner
guarantees that if ithasNextInt()
, thennextInt()
will peacefully give you thatint
, and will not throw anyNumberFormatException
/InputMismatchException
/NoSuchElementException
.- How to use Scanner to accept only valid int as input
- How do I keep a scanner from throwing exceptions when the wrong type is entered? (java)
请注意,上面的代码段包含
sc.next()
用于推进扫描器
的语句,直到hasNextInt()
。重要的是要意识到hasNextXXX
方法的 none 推进扫描仪
通过任何输入!你会发现如果从代码片段中省略这一行,那么它会在无效输入上进入无限循环!Note that the snippet above contains a
sc.next()
statement to advance theScanner
until ithasNextInt()
. It's important to realize that none of thehasNextXXX
methods advance theScanner
past any input! You will find that if you omit this line from the snippet, then it'd go into an infinite loop on an invalid input!这有两个结果:
- 如果你需要跳过垃圾输入如果您的
hasNextXXX
测试失败,那么您需要以某种方式推进扫描仪
(例如next()
,nextLine()
,skip
等。) - 如果一个
hasNextXXX
测试失败,你可以仍然测试它是否hasNextYYY
!
- If you need to skip the "garbage" input that fails your
hasNextXXX
test, then you need to advance theScanner
one way or another (e.g.next()
,nextLine()
,skip
, etc). - If one
hasNextXXX
test fails, you can still test if it perhapshasNextYYY
!
以下是执行多个
hasNextXXX
测试的示例。Here's an example of performing multiple
hasNextXXX
tests.Scanner sc = new Scanner(System.in); while (!sc.hasNext("exit")) { System.out.println( sc.hasNextInt() ? "(int) " + sc.nextInt() : sc.hasNextLong() ? "(long) " + sc.nextLong() : sc.hasNextDouble() ? "(double) " + sc.nextDouble() : sc.hasNextBoolean() ? "(boolean) " + sc.nextBoolean() : "(String) " + sc.next() ); }
这是一个示例会话:
5
(int)5
false
(布尔值)false
blah
(String)blah
1.1
(双倍)1.1
100000000000
(长)100000000000
退出5
(int) 5
false
(boolean) false
blah
(String) blah
1.1
(double) 1.1
100000000000
(long) 100000000000
exit请注意,测试的顺序很重要。如果
扫描仪
hasNextInt()
,那么它还hasNextLong()
,但它不一定是true
反之亦然。通常情况下,您希望在更一般的测试之前进行更具体的测试。Note that the order of the tests matters. If a
Scanner
hasNextInt()
, then it alsohasNextLong()
, but it's not necessarilytrue
the other way around. More often than not you'd want to do the more specific test before the more general test.扫描仪
具有正则表达式支持的许多高级功能。以下是使用它来验证元音的示例。Scanner
has many advanced features supported by regular expressions. Here's an example of using it to validate vowels.Scanner sc = new Scanner(System.in); System.out.println("Please enter a vowel, lowercase!"); while (!sc.hasNext("[aeiou]")) { System.out.println("That's not a vowel!"); sc.next(); } String vowel = sc.next(); System.out.println("Thank you! Got " + vowel);
这是一个示例会话:
请输入元音,小写!
5
这不是元音!
z
这不是元音!
$ b $是
谢谢!得到Please enter a vowel, lowercase!
5
That's not a vowel!
z
That's not a vowel!
e
Thank you! Got e在正则表达式中,作为Java字符串文字,模式
[aeiou]
就是所谓的角色类;它匹配任何字母a
,e
,i
,o
,u
。请注意,使上述测试不区分大小写非常简单:只需为Scanner
提供此类正则表达式模式。In regex, as a Java string literal, the pattern
"[aeiou]"
is what is called a "character class"; it matches any of the lettersa
,e
,i
,o
,u
. Note that it's trivial to make the above test case-insensitive: just provide such regex pattern to theScanner
.-
hasNext(String pattern)
- 返回true
如果下一个标记与从指定字符串构造的模式匹配。 -
java.util.regex.Pattern
hasNext(String pattern)
- Returnstrue
if the next token matches the pattern constructed from the specified string.java.util.regex.Pattern
- Java Tutorials/Essential Classes/Regular Expressions
- regular-expressions.info/Character Classes
有时你需要逐行扫描,一行上有多个令牌。完成此操作的最简单方法是使用两个
扫描程序
,其中第二个扫描程序
需要第一个Scanner
中的nextLine()
作为输入。这是一个例子:Sometimes you need to scan line-by-line, with multiple tokens on a line. The easiest way to accomplish this is to use two
Scanner
, where the secondScanner
takes thenextLine()
from the firstScanner
as input. Here's an example:Scanner sc = new Scanner(System.in); System.out.println("Give me a bunch of numbers in a line (or 'exit')"); while (!sc.hasNext("exit")) { Scanner lineSc = new Scanner(sc.nextLine()); int sum = 0; while (lineSc.hasNextInt()) { sum += lineSc.nextInt(); } System.out.println("Sum is " + sum); }
这是一个示例会话:
在一行(或退出)中给我一堆数字
3 4 5
总和为12
10 100百万美元
总和是110
等什么?
总和为0
退出Give me a bunch of numbers in a line (or 'exit')
3 4 5
Sum is 12
10 100 a million dollar
Sum is 110
wait what?
Sum is 0
exit除了
Scanner(String)
构造函数,还有扫描仪(java.io.File)
等。-
扫描仪
提供丰富的功能,例如hasNextXXX
验证方法。 - 正确使用
hasNextXXX / nextXXX
组合意味着扫描仪
将从不抛出InputMismatchException
/NoSuchElementException
。 - 始终请记住,
hasNextXXX
不会超过任何输入扫描仪
。 - Don如果有必要,不要创建多个
扫描器
。两个简单的扫描程序
通常比一个过于复杂的扫描程序
好。 - 最后即使您没有任何计划使用高级正则表达式功能,请记住哪些方法是基于正则表达式的,哪些不是。采用
字符串模式
参数的任何Scanner
方法都是基于regex的。
- 提示:将任何
字符串
转换为文字的简便方法模式是Pattern.quote
它。
Scanner
provides a rich set of features, such ashasNextXXX
methods for validation.- Proper usage of
hasNextXXX/nextXXX
in combination means that aScanner
will NEVER throw anInputMismatchException
/NoSuchElementException
. - Always remember that
hasNextXXX
does not advance theScanner
past any input. - Don't be shy to create multiple
Scanner
if necessary. Two simpleScanner
is often better than one overly complexScanner
. - Finally, even if you don't have any plans to use the advanced regex features, do keep in mind which methods are regex-based and which aren't. Any
Scanner
method that takes aString pattern
argument is regex-based.- Tip: an easy way to turn any
String
into a literal pattern is toPattern.quote
it.
这篇关于使用java.util.Scanner验证输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- Tip: an easy way to turn any
- 提示:将任何
-