Каковы недостатки сканирования с регулярными выражениями в Java

2

Я знаю, что в дополнение к сканированию для предопределенных primitive типов я также могу сканировать свои собственные пользовательские шаблоны, что полезно при сканировании более сложных данных. Я говорю о Scanner.next(String pattern). Однако в книге, которую я читал о Java, есть абзац, который гласит:

"Это нужно сделать при регулярном выражении. Шаблон сопоставляется только с следующим входным токеном, поэтому, если ваш шаблон содержит разделитель, он никогда не будет согласован".

Я действительно не понимаю, что это значит, и в каких ситуациях этот тип сканирования неприменим

  • 0
    На какую книгу вы ссылаетесь? ТАК не сайт проверки для произвольного невостребованного мусора.
  • 1
    Размышление на Яве, 4-е издание - Брюс Экель
Теги:
java.util.scanner

2 ответа

2
Лучший ответ

Представьте, что у вас есть запятая , как разделитель. Теперь каким-то образом (возможно, это был предоставлен кем-то другим) вы придумали шаблон ab,cd. Поскольку шаблон содержит разделитель, сканер попытается сопоставить ab,cd сначала с ab и затем с cd, что не приведет к совпадению.

Обратите внимание, что это предостережение, и это не обязательно то, с чем вы легко столкнетесь.

  • 0
    Можете ли вы объяснить, как используются разделитель и шаблон в вашем примере? Я думал, что шаблон будет использоваться сканером в качестве разделителя . Как это может быть 2 разные вещи?
  • 0
    @Codebender Так же, как nextInt() будет сканировать целое число (с \n в качестве разделителя и какими бы то ни было разделителями по умолчанию), next(String pattern) будет сканировать следующий ввод, соответствующий шаблону. Входные данные сначала маркируются в соответствии с разделителями, после чего выполняется сопоставление, будь то шаблон регулярного выражения, целое число, строка и т. Д.
Показать ещё 1 комментарий
0

Говоря об исходном примере, приведенном в книге "Мышление на 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})");
                                                //    ^^

Ещё вопросы

Сообщество Overcoder
Наверх
Меню