Подтвердить что ты не робот

Pattern.matcher() vs pattern.matches()

Мне интересно, почему результаты java regex pattern.matcher() и pattern.matches() отличаются при условии того же регулярного выражения и той же строки

String str = "hello+";
Pattern pattern = Pattern.compile("\\+");
Matcher matcher = pattern.matcher(str);

while (matcher.find()) {
    System.out.println("I found the text " + matcher.group() + " starting at " 
        + "index " + matcher.start() + " and ending at index " + matcher.end());
}

System.out.println(java.util.regex.Pattern.matches("\\+", str));

Результат выше:

I found the text + starting at index 5 and ending at index 6
false

Я обнаружил, что использование выражения для соответствия полной строке отлично работает в случае matches(".*\\+").

4b9b3361

Ответ 1

pattern.matcher(String s) возвращает a Matcher, который может находить шаблоны в String s. pattern.matches(String str), если вся строка (str) соответствует шаблону.

Вкратце (просто чтобы запомнить разницу):

  • pattern.matcher - проверьте, если строка содержит шаблон
  • pattern.matches - проверьте, если строка -

Ответ 2

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

Pattern.matches(String regex, CharSequence input) компилирует регулярное выражение в Matcher и возвращает Matcher.matches().

Matcher.matches пытается сопоставить область целая (строка) с шаблоном (Regex).

Итак, в вашем случае Pattern.matches("\\+", str) возвращает false, поскольку str.equals("+") имеет значение false.

Ответ 3

Из Javadoc, см. if, и только если, раздел всей области

   /**
     * Attempts to match the entire region against the pattern.
     *
     * <p> If the match succeeds then more information can be obtained via the
     * <tt>start</tt>, <tt>end</tt>, and <tt>group</tt> methods.  </p>
     *
     * @return  <tt>true</tt> if, and only if, <b>the entire region</b> sequence
     *          matches this matcher pattern
     */
    public boolean matches() {
        return match(from, ENDANCHOR);
    }

Итак, если ваша строка была просто "+", вы получите истинный результат.

Ответ 4

match пытается сопоставить выражение со всей строкой. Смысл, он проверяет, является ли вся строка патерном или нет. концептуально думаю, что это так, он неявно добавляет a ^ в начале и $в конце вашего шаблона.

For, String str = "hello +", если вы хотите, чтобы match() возвращал true, вам нужно иметь шаблон типа ".\+."

Надеюсь, это ответ на ваш вопрос.

Ответ 5

Pattern.matches тестирует всю строку, в вашем случае вы должны использовать:

 System.out.println(java.util.regex.Pattern.matches(".*\\+", str));

Значение любой строки и символа +

Ответ 6

Я думаю, что ваш вопрос должен быть действительно "Когда я должен использовать метод Pattern.matches()?", и ответ "Никогда". Вы ожидали, что он вернет массив согласованных подстрок, например .NET Matches? Это вполне разумное ожидание, но нет, Java не имеет ничего подобного.

Если вы просто хотите выполнить быстрое и грязное совпадение, украсьте регулярное выражение с помощью .* с обоих концов и используйте собственный метод matches():

System.out.println(str.matches(".*\\+.*"));

Если вы хотите извлечь несколько совпадений или получить доступ к информации о совпадении после этого, создайте экземпляр Matcher и используйте его методы, как в вашем вопросе. Pattern.matches() - не что иное, как потерянная возможность.