Разбор шаблонов Java - PullRequest
       1

Разбор шаблонов Java

2 голосов
/ 15 апреля 2011

Представьте, что моя цель в программе - разобрать как можно больше вхождений "ab" из строки.Я подхожу к этой проблеме с помощью следующего кода:

public static void main(String[] args)
{
    final String expression = "^(\\s*ab)";

    Scanner scanner = new Scanner("ab abab  ab");

    while (scanner.hasNext())
    {
        String next = scanner.findWithinHorizon(expression, 0);

        if (next == null)
        {
            System.out.println("FAIL");
            break;
        }
        else
        {
            System.out.println(next);
        }
    }
}

Знак в начале выражения должен запрещать что-либо, кроме пробелов в начале каждого чтения, как упомянуто здесь .Это сделано для того, чтобы запретить что-то вроде "cab" или "c ab".На самом деле, я ожидаю, что null будет возвращен и FAIL будет напечатан на консоли, если произойдет один из этих двух случаев.Если я удаляю знак вставки из выражения, он отлично работает на вводе, таком как "ab abab ab", но не возвращает ноль для "c ab".С другой стороны, если я оставлю каретку, "c ab" вернет ноль, как и ожидалось, но "ab abab ab" не удастся.Как я могу сделать эту работу?

Редактировать

Мой оригинальный пост, возможно, был немного расплывчатым.Пример, который я привел выше, является более простой версией моей реальной проблемы.шаблон ab является шаблоном-заполнителем, который я бы заменил на что-то более интересное, скажем, адрес электронной почты, регулярное выражение или шестнадцатеричное значение.

В моем приложении вход для сканера - это не строка, а поток ввода, о котором я ничего не знаю.Моя цель в цикле - читать значения по одному из входных данных и проверять их содержимое на соответствие некоторому шаблону.Если они это сделают, то я мог бы сделать что-то более интересное с ними.Если нет, то программа завершается.

В вышеприведенном примере я ожидал бы, что на вход ab abab выводим:

ab
 ab
ab
  ab

Я ожидаю, что c ab выведет:

FAIL

и я ожидаю, что ab cab выведет:

ab
FAIL

Ответы [ 4 ]

4 голосов
/ 15 апреля 2011

В другой ветке вы хотели сопоставить первое вхождение ab, поэтому каретка была в порядке. Если вы хотите соответствовать каждому вхождению ab до появления другого символа, попробуйте это выражение: String expression = "\\G(\\s*ab)";

\G означает, что следующий матч должен начинаться с позиции, на которой остановился предыдущий.

Если я использую это с вашим кодом, я получаю следующие результаты:

  1. Input = "ab abab ab", Output = "ab", "ab", "ab", "ab"

  2. Вход = " c ab abab ab", Выход = "FAIL"

  3. Вход = "ab c abab ab", Выход = "ab", "FAIL"

  4. Вход = "ab abab ab c ", Выход = "ab", "ab", "ab", "ab", "FAIL"

0 голосов
/ 15 апреля 2011

Если я правильно понял ваш вопрос, ошибка в выражении. Если вы всегда хотите пробел в начале, вы должны использовать ^ (\ s +), а не ^ (\ s *), так как * может быть 0 вхождений, а + означает по крайней мере один.

0 голосов
/ 15 апреля 2011

Пожалуйста, поймите, что метод findWithinHorizon в Сканере предназначен для нахождения следующего вхождения шаблона, построенного из указанной строки , а НЕ для сопоставления всего ввода. Если вы напишете регулярное выражение, которое соответствует всему вводу, то оно просто вернет введенный текст как (согласно ответу В.М. Микита здесь). Но этого не хочешь, как я понимаю.

Так что вам нужно сделать отдельный вызов метода String # соответствует , чтобы убедиться, что перед вашим текстом нет ничего, кроме пробелов, и, если он совпадает, просто найдите все ab вхождений.

Учтите это незначительное изменение в вашем коде:

public static void main(String[] args) {
   matchIt("ab abab  ab");
   matchIt("c ab");
   matchIt("cab");
}

private static void matchIt(String str) {
   final String expression = "ab";
   System.out.println("Input: [" + str + ']');
   Scanner scanner = new Scanner(str);

   if(str.matches("^\\s*ab.*$")) {
      while (scanner.hasNext()) {
         String next = scanner.findWithinHorizon(expression, 0);
         if (next == null) {
            System.out.println("FAIL");
            break;
         }
         else {
            System.out.println(next);
         }
      }
   }
   else
      System.out.println("FAIL");
}

ВЫВОД:

Input: [ab abab  ab]
ab
ab
ab
ab
===========================
Input: [c ab]
FAIL
===========================
Input: [cab]
FAIL
===========================
0 голосов
/ 15 апреля 2011

Ну ... Я думаю, что вы можете сделать это одним вызовом регулярного выражения

Попробуйте следующий шаблон:

expression = "^(\\s*ab*)*$";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...