Я знаю, что в дополнение к сканированию для предопределенных primitive
типов я также могу сканировать свои собственные пользовательские шаблоны, что полезно при сканировании более сложных данных. Я говорю о Scanner.next(String pattern)
. Однако в книге, которую я читал о Java, есть абзац, который гласит:
"Это нужно сделать при регулярном выражении. Шаблон сопоставляется только с следующим входным токеном, поэтому, если ваш шаблон содержит разделитель, он никогда не будет согласован".
Я действительно не понимаю, что это значит, и в каких ситуациях этот тип сканирования неприменим
Представьте, что у вас есть запятая ,
как разделитель. Теперь каким-то образом (возможно, это был предоставлен кем-то другим) вы придумали шаблон ab,cd
. Поскольку шаблон содержит разделитель, сканер попытается сопоставить ab,cd
сначала с ab
и затем с cd
, что не приведет к совпадению.
Обратите внимание, что это предостережение, и это не обязательно то, с чем вы легко столкнетесь.
nextInt()
будет сканировать целое число (с \n
в качестве разделителя и какими бы то ни было разделителями по умолчанию), next(String pattern)
будет сканировать следующий ввод, соответствующий шаблону. Входные данные сначала маркируются в соответствии с разделителями, после чего выполняется сопоставление, будь то шаблон регулярного выражения, целое число, строка и т. Д.
Говоря об исходном примере, приведенном в книге "Мышление на 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));
}
правильно печатает желаемый результат. Но, если вы немного измените его, заменив @
в угрозеData пробелом ' '
и @
в шаблоне с \\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})");
// ^^