我的程序需要接受整数,单个字符或一个特定字符串(在本例中我将使用"pear"
)。虽然这些中的每一个都可以用空格分隔,但不应该有任何需要。
目前,我的解析代码依赖于Scanner
,看起来像这样:
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
if (scanner.hasNext("\\s+")) {
// Ignore whitespace…
} else if (scanner.hasNext("[-]?\\d+")) {
// Get a number
String nextNumberString = scanner.next("[-]?\\d+");
// Process the string representing the number…
} else if (scanner.hasNext("pear")) {
scanner.next("pear");
// Do something special…
} else {
// Get the next character
Pattern oldDelimiter = scanner.delimiter();
scanner.useDelimiter("");
String nextCharAsString = scanner.next();
scanner.useDelimiter(oldDelimiter);
char nextCharacter = nextCharAsString.charAt(0);
if (Character.isWhitespace(nextCharacter)) {
// Ignore whitespace…
} else {
// Process character…
}
}
}
目前,我的程序会接受123 d 456 r pear
这样的输入,没有任何问题。但是,它也应该接受没有任何空格(123d456rpear
)的相同输入,并以相同的方式解释它,并且使用我当前的代码,各个数字被错误地解释为字符。
我觉得原因可能是我正在使用的正则表达式。但是,将.*
添加到它们的末尾将导致解析所有后续字符以及我尝试解析的输入。例如,[-]?\d+.*
会尝试将整个123d456rpear
解析为一个数字,当我真的只想要123
时,其余部分将在稍后进行解析。我也尝试将我想要的输入包装到一个组中,然后附加?
或{1}
,这些都没有用。
我也尝试了scanner.findInLine()
,但在我的测试中,这似乎也没有用。例如,当我尝试这样做时,pearpear
会导致无限循环,尽管我试图跳过pear
的第一个实例。
我也尝试将分隔符设置为""
,就像我在提取单个字符时一样(在这种情况下,按预期工作)。但是,这会导致单独处理每个单独的数字,解析1
,2
和3
而不是123
。 pear
也被解释为单个字符。
那么,有人可以帮我弄明白我哪里错了吗?这个问题是我的正则表达式吗?我使用了错误的方法吗?或者我误解了Scanner
课程的设计方式是什么?
答案 0 :(得分:2)
据我所知,Scanner类的想法是提取令牌并将分隔符扔掉。但是你不想丢掉任何东西,只留下空白。但是输入中不需要空格。这是一个使用外部和内部扫描仪的实现思路。外部标记为空格 - 如果有的话。内部使用findInLine()
来绕过分隔符。
findInLine
尝试找到从中构造的下一个模式 指定的字符串,忽略分隔符。
public void scan(Scanner scanner) {
while (scanner.hasNext()) {
String next = scanner.next();
System.out.println("opening inner scanner: " + next);
Scanner innerScanner = new Scanner(next);
do {
next = innerScanner.findInLine("([-]?\\d+)|(pear)|([a-zA-Z])");
if (next == null) {
// Nothing useful in there
} else if (next.equals("pear")) {
System.out.println("pear");
} else if (next.matches("[a-zA-Z]")) {
System.out.println("char: " + next);
} else {
System.out.println("number: " + next);
}
} while (next != null);
innerScanner.close();
}
}
public void run() {
scan(new Scanner("123 d 456 pear"));
scan(new Scanner("123d456pear"));
}
run()
方法的输出如下:
opening inner scanner: 123
number: 123
opening inner scanner: d
char: d
opening inner scanner: 456
number: 456
opening inner scanner: pear
pear
opening inner scanner: 123d456pear
number: 123
char: d
number: 456
pear
答案 1 :(得分:0)
好the individual digits are incorrectly interpreted as characters
因为扫描程序的hasNext
方法从delimiter提供的标记中提取了默认为空白的标记
来自java docs
扫描仪使用分隔符模式将其输入分解为标记, 默认情况下匹配空格。然后可以得到所产生的令牌 使用各种下一个转换为不同类型的值 方法
因此提取了整个123d456rpear
,它不是数字而是字符串