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(".*\\+")
.
Ответы
Ответ 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()
- не что иное, как потерянная возможность.