Проблема реализации частичных совпадений с регулярным выражением на Android

Я создаю регулярное выражение, чтобы оценить, является ли IP-адрес действительным адресом многоадресной рассылки. Эта проверка происходит в режиме реального времени, пока вы печатаете (если вы вводите недопустимый символ / символ вне диапазона, он не принимается), поэтому я не могу просто сравнить конечный результат с регулярным выражением. Проблема, с которой я сталкиваюсь, заключается в том, что она допускает двойной период после каждой группы чисел (224.., 224.0.., 224.0.0.. все отображаются как действительные).

Код ниже представляет собой статическое представление того, что происходит. Почему-то 224.. показывается как легальная стоимость. Я протестировал это регулярное выражение онлайн (не в java'ized: ^2(2[4-9]|3\d)(.(25[0-5]|2[0-4]\d|1\d) \d|[1-9]\d|\d)){3}$), и он отлично работает и не принимает неверный ввод, который я описываю.

Pattern p = Pattern.compile("^2(2[4-9]|3\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$");
Matcher m = p.matcher("224..");


if (!m.matches() && !m.hitEnd()) {
    System.out.println("Invalid");
} else {
    System.out.println("Valid");
}

Кажется, что метод m.hitEnd() оценивается как истина всякий раз, когда я вводю 224, что для меня не имеет смысла. Если кто-то мог бы, пожалуйста, просмотреть это и убедиться, что я не делаю очевидной ошибки, и, возможно, объяснить, почему hitEnd () возвращает true в этом случае, я был бы признателен. Спасибо всем.

4 ответа

Решение

Проведя некоторую оценку себя (обнаружив, что это на Android), я понял, что тот же код реагирует на Dalvik иначе, чем на обычной JVM.

Код является:

   Pattern p = Pattern.compile("^2(2[4-9]|3\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$");
    Matcher m = p.matcher("224..");

    if (!m.matches() && !m.hitEnd()) {
        System.out.println("Invalid");
    } else {
        System.out.println("Valid");
    }

Этот код (хотя и немного измененный) печатает Valid на Android и Invalid на JVM.

Я не знаю, как вы проверили свое регулярное выражение, но оно не выглядит правильным в соответствии с вашим описанием.

Ваше регулярное текст требует всех 4 разделов цифр. Нет шансов, что он совпадет с 224. Только [0-1] и \d помечены знаком вопроса и поэтому являются необязательными.

Итак, не имея дело с деталями ограничений, которые разрешены конкретные цифры, я бы предложил вам что-то вроде этого:

^\\d{1-3}\\.(\\d{0-3}\\.)?(\\d{0-3}\\.)?(\\d{0-3}\\.)?$

И вам не нужно использовать hitEnd(): $ в конце достаточно. И не использовать matches(), использование find() вместо. matches() как find() но добавляет ^ и $ автоматически.

Я только что проверил ваш код и m.hitEnd() оценивается как ложное для меня, и я получаю недействительным...

Так что я не совсем уверен, в чем проблема?

Я сообщил об ошибке 20625 в Dalvik. Тем временем вам не нужно использовать hitEnd()имея $ суффикс должен быть достаточным.

public void testHitEnd() {
  String text = "b";
  String pattern = "^aa$";
  Matcher matcher = Pattern.compile(pattern).matcher(text);
  assertFalse(matcher.matches());
  assertFalse(matcher.hitEnd());
}
Другие вопросы по тегам