Проблема реализации частичных совпадений с регулярным выражением на 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());
}