2014-02-11 3 views
1

Почему этот шаблон не соответствует порту в моем URL-адресе?Почему это регулярное выражение java не работает?

public class PatternTest { 
    private Pattern PORT_STRING_PATTERN = Pattern.compile(":\\d+/"); 

    private boolean hasPort(String url) { 
     return PORT_STRING_PATTERN.matcher(url).matches(); 
    } 

    @Test 
    public void testUrlHasPort() { 
     assertTrue("does not have port", hasPort("http://www.google.com:80/")); 
    } 
} 

Если изменить шаблон на Pattern.compile("^.+:\\d+/") это делает матч. Зачем мне нужен ^.+?

ответ

14

Проблема заключается в том, что вы используете Matcher.matches(), который документированный как:

пытается сопоставить весь регион с шаблоном.

Вы не хотите, чтобы соответствовать всему региону - вы просто хотите, чтобы найти соответствие в регионе.

Я думаю, что вы, вероятно, хотите, чтобы называть find() вместо:

Попытки найти следующую подпоследовательность последовательности ввода, которая соответствует шаблону.

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

+0

Yup, классическая ошибка и (imho) ошибка от разработчиков API Java API для начала. – fge

+0

@fge: По моему скромному мнению, я не думаю, что это ошибка. Поскольку для проверки правильности требуется «конец строки» (когда вы используете 'match' на других языках), обычно используется' $ ', хотя это не всегда означает абсолютный конец строки. Если строка заканчивается последовательностью терминатора линии, то '$' может совпадать прямо перед ней. – nhahtdh

+0

@nhahtdh: Имея два доступных вызова, имеет смысл. Однако вызов «совпадения всей области» вызывает «совпадения». –

4

Это потому, что Matcher#matches пытается совместить весь ввод. Вместо этого вам нужно matcher#find().

Смежные вопросы