我知道除了扫描预定义的primitive
类型之外,我还可以扫描我自己的用户定义模式,这在扫描更复杂的数据时很有用。我在谈论Scanner.next(String pattern)
方法。但是,在我读到的关于Java的书中,有一段说
“使用正则表达式进行扫描时有一点需要注意。模式仅与下一个输入标记匹配,因此如果您的模式包含分隔符,则永远不会匹配。”
我真的不明白这意味着什么,在哪种情况下这种类型的扫描不适用
想象一下,你有一个逗号,
作为分隔符。现在不知何故(也许是由其他人提供)你想出了一个模式ab,cd
。由于模式包含分隔符,扫描程序将尝试首先将ab,cd
与ab
匹配,然后再与cd
匹配,从而导致无法匹配。
请注意,这是一个警告,并不一定是您很容易遇到的事情。
谈到“Thinking in Java”一书中给出的原始示例,该程序:
String threatData =
"58.27.82.161@02/10/2005\n" +
"204.45.234.40@02/11/2005\n" +
"58.27.82.161@02/11/2005\n" +
"58.27.82.161@02/12/2005\n" +
"58.27.82.161@02/12/2005\n" +
"[Next log section with different data format]";
Scanner sc = new Scanner(threatData);
Pattern pattern = Pattern.compile("(\\d+([.]\\d+){3})@" + "(\\d{2}/\\d{2}/\\d{4})");
/// ^
while(sc.hasNext(pattern)) {
System.out.println(sc.next(pattern));
MatchResult matchResult = sc.match();
System.out.println("Threat from " + matchResult.group(1) + " on " + matchResult.group(3));
}
正确打印所需的输出。但是,当你通过用@
模式替换带有空格' '
和@
的threatData中的\\s
进行轻微更改时,你会发现扫描程序无法匹配模式,因为它包含默认分隔符。
String threatData =
"58.27.82.161 02/10/2005\n" +
"204.45.234.40 02/11/2005\n" +
"58.27.82.161 02/11/2005\n" +
"58.27.82.161 02/12/2005\n" +
"58.27.82.161 02/12/2005\n" +
"[Next log section with different data format]";
Scanner sc = new Scanner(threatData);
Pattern pattern = Pattern.compile("(\\d+([.]\\d+){3})\\s" + "(\\d{2}/\\d{2}/\\d{4})");
// ^^