我读过一些其他的帖子,不能确定下面的代码有什么问题,为什么会抛出异常:
public static void main(String[] args) {
Scanner scanner = new Scanner(" 0 B 2 # L");
String first = scanner.next("[0-9]+ [abB#]");
String second = scanner.next("[0-9]+ [abB#] [LR]");
System.out.println(first);
System.out.println(second);
}
预期输出:0 B
2 # L
引用javadoc的Scanner.next(String)
:
如果匹配由指定字符串构造的模式,则返回下一个标记。
默认情况下(您没有更改它),Scanner
将在空白上分割令牌,因此Scanner
返回的令牌如下:
"0"
"B"
"2"
"#"
"L"
第一个next
令牌是"0"
,它与"[0-9]+ [abB#]"
不匹配,所以你得到InputMismatchException
。
不要使用Scanner
。
Pattern p = Pattern.compile(" *([0-9]+ [abB#]) +([0-9]+ [abB#] [LR]) *");
Matcher m = p.matcher(" 0 B 2 # L");
if (m.matches()) {
System.out.println(m.group(1));
System.out.println(m.group(2));
}
当使用Scanner
时,它分隔整个输入。在您的示例中,它用空格分隔(默认):
Scanner
使用分隔符模式将其输入分解为多个令牌,默认情况下匹配空白。
@Andreas描述了异常的根本原因。
现在,解决方案是使用忽略分隔符的方法。
findInLine(java.lang.String)
、findWithinHorizon(java.lang.String, int)
和skip(java.util.regex.Pattern)
方法的操作独立于分隔符模式。这些方法将尝试匹配指定的模式,而不考虑输入中的分隔符,因此可以在分隔符不相关的特殊情况下使用。
可以使用Scanner.findInLine
:
Scanner s = new Scanner(" 0 B 2 # L");
String first = s.findInLine("[0-9]+ [abB#]"); // => 0 B
System.out.println(first);
String second = s.findInLine("[0-9]+ [abB#] [LR]"); // => 2 # L
System.out.println(second);
s.close();
参见IDEONE demo
一个简单的Matcher
正则表达式解决方案:
String str = " 0 B 2 # L";
Pattern ptrn = Pattern.compile("[0-9]+ [abB#] [LR]|[0-9]+ [abB#]");
Matcher matcher = ptrn.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
参见IDEONE demo
长选项必须出现在短选项之前才能获得正确匹配