Matcher.matches(): примеры (JAVA)
Matcher.matches(): booleanОписание метода Matcher.matches()
Метод Matcher.matches() в Java проверяет, соответствует ли весь проверяемый регион регулярному выражению. Метод объявлен в классе java.util.regex.Matcher и не принимает аргументов. Возвращаемое значение - логический тип boolean: true, если регулярное выражение совпало со всем текущим регионом сопоставления, и false в противном случае.
Ключевые моменты работы:
- Сравнение выполняется для всего региона, на который указывает
Matcher. По умолчанию регион - вся строка, переданная вPattern.matcher(CharSequence)или вMatcher.reset(CharSequence). - Если в шаблоне используются якоря
^и$, их поведение может меняться при установке флаговMULTILINEи прозрачных/якорных границ (методыuseTransparentBoundsиuseAnchoringBoundsуMatcher). - Флаги компиляции шаблона (
Pattern.CASE_INSENSITIVE,Pattern.DOTALLи др.) влияют на результат. Встроенные флаги с синтаксисом(?i),(?s)и т. п. тоже работают. - Для частичного поиска подстроки следует использовать
Matcher.find()или методString.indexOf. matches() требует полного соответствия региона.
Примеры возвращаемых значений в общих случаях:
- Паттерн
\d+и текст"123"-true. - Тот же паттерн и текст
"a123"-false. - Паттерн
.*и многострочный текст при отсутствииDOTALL-false, если в шаблоне ожидается, что точка захватывает перевод строки; при включённомDOTALLрезультат будетtrue.
Альтернативный путь получения полного совпадения - статический метод Pattern.matches(String regex, CharSequence input), который компилирует шаблон и вызывает matches() один раз; при повторных проверках выгоднее переиспользовать объект Pattern.
Короткие примеры использования
Ниже несколько простых случаев с кодом и выводом.
// Пример 1: полное цифровое совпадение
import java.util.regex.*;
class Ex1{
public static void main(String[] a){
Pattern p = Pattern.compile("\\d+");
Matcher m1 = p.matcher("123");
Matcher m2 = p.matcher("a123");
System.out.println(m1.matches()); // true
System.out.println(m2.matches()); // false
}
}
true false
// Пример 2: отличие от find()
import java.util.regex.*;
class Ex2{
public static void main(String[] a){
Pattern p = Pattern.compile("abc");
Matcher m = p.matcher("xabcx");
System.out.println(m.find()); // true - нашли подстроку
System.out.println(m.matches()); // false - не всё соответствует
}
}
true false
// Пример 3: флаг DOTALL влияет на точку
import java.util.regex.*;
class Ex3{
public static void main(String[] a){
Pattern p1 = Pattern.compile(".*");
Pattern p2 = Pattern.compile(".*", Pattern.DOTALL);
String s = "line1\nline2";
System.out.println(p1.matcher(s).matches()); // false без DOTALL
System.out.println(p2.matcher(s).matches()); // true с DOTALL
}
}
false true
// Пример 4: использование Pattern.matches (одноразово)
class Ex4{
public static void main(String[] a){
System.out.println(java.util.regex.Pattern.matches("hello", "hello")); // true
System.out.println(java.util.regex.Pattern.matches("hello", "xhellox")); // false
}
}
true false
Похожие методы в Java и их особенности
- Matcher.find() - ищет следующее вхождение шаблона в регионе, подходит для поиска подстрок.
- Matcher.lookingAt() - проверяет соответствие шаблона началу региона, не требует полного совпадения.
- Pattern.matches() - статический удобный вызов для одноразовой проверки полного совпадения, но при многократном использовании неэффективен из-за перекомпиляции шаблона.
- String.matches() - проксирует к
Pattern.matches, компилирует шаблон при каждом вызове; приемлем для редких проверок, не для циклов.
Выбор зависит от задачи: для поиска подстрок предпочтительнее find(), для сравнений начала - lookingAt(), для одноразовых проверок коротокодовых случаев - Pattern.matches(), при многократном применении выгоднее переиспользовать Pattern и Matcher.
Аналоги в других языках и отличия
- PHP:
preg_match- возвращает 1 при нахождении соответствия (обычно подстрока). Для проверки полного совпадения требуется якорить шаблон^...$или использовать модификаторDв PCRE. Пример:<? $re = '/^\\d+$/'; var_dump(preg_match($re, '123')); // 1 var_dump(preg_match($re, 'a123')); // 0 ?>int(1) int(0)
- JavaScript:
RegExp.test()проверяет наличие соответствия где угодно. Для полного совпадения добавляются якоря^и$.const r = /^\d+$/; console.log(r.test('123')); console.log(r.test('a123'));true false
- Python:
re.fullmatch()matches(),re.match()проверяет начало,re.search()ищет вхождение. Пример:import re print(bool(re.fullmatch(r"\d+", "123"))) print(bool(re.fullmatch(r"\d+", "a123")))True False
- SQL: в PostgreSQL оператор
~ищет соответствие где угодно; для полного совпадения используются якори^...$или функция~с шаблоном, охватывающим всю строку. В некоторых СУБД естьREGEXP_LIKE. - C#:
Regex.IsMatchпо умолчанию ищет вхождение; для полного совпадения добавляются якоря или проверяется длина совпадения уMatch. Флаги задаются черезRegexOptions. - Lua:
string.matchиспользует собственный шаблонизатор, поведение отличается от PCRE; для полноценной регэксп-поддержки применяется библиотека LPEG или модуль на базе PCRE. - Go:
regexp.MatchStringсообщает о наличии совпадения (подстрока); для полного соответствия добавляются якори^$. - Kotlin: наследует поведение Java и API
java.util.regex, поэтомуMatcher.matches()и рекомендации те же самые.
Типичные ошибки при использовании
- Ожидание поиска подстроки при вызове
matches(). Частая путаница:matches()требует полного совпадения. Пример ошибки:Pattern p = Pattern.compile("abc"); Matcher m = p.matcher("xabcx"); System.out.println(m.matches()); // часто ожидают true, но будет falsefalse
- Регулярное выражение без якорей воспринимается как шаблон для части строки в некоторых языках, но в Java
matches()всё равно проверит весь регион. Это приводит к неожиданностям при переносе кода между языками. - Повторная компиляция шаблона при больших объёмах: использование
String.matchesв циклах снижает производительность из-за компиляции на каждый вызов. Пример:for(String s: list){ if(s.matches("\\d+")) { ... } } // Лучше вынести Pattern.compile("\\d+") отдельно - Игнорирование флагов, влияющих на
^,$и поведение точки. Пример: ожидание, что '.' покроет перевод строки без флага DOTALL. - Попытка переиспользовать один и тот же
Matcherв нескольких потоках.Matcherне потокобезопасен.
Изменения в API и поведение в новых версиях
Само поведение Matcher.matches() стабильно с ранних версий Java и существенных изменений не претерпело. В более новых релизах языка добавлялись сопутствующие возможности в API регулярных выражений, которые дополняют работу с совпадениями, но не меняют базовой логики matches(). В частности, в последних версиях была добавлена поддержка потокового получения совпадений через метод Matcher.results(), а также появились дополнительные свойства у Pattern и улучшения производительности в реализации движка регулярных выражений. Поведение якорей, флагов и регионов осталось совместимым с существующими спецификациями, поэтому старые примеры обычно продолжают работать без изменений.
Расширенные и редкие сценарии применения
Ниже несколько более сложных случаев с пояснениями.
// Advanced 1: использование region для проверки части строки
import java.util.regex.*;
class Adv1{
public static void main(String[] a){
Pattern p = Pattern.compile("\\w+");
Matcher m = p.matcher("xxx123yyy");
m.region(3, 6); // ограничение региона на подпоследовательность "123"
System.out.println(m.matches()); // true, потому что регион полностью соответствует шаблону
}
}
true
// Advanced 2: сочетание флагов и якорей
import java.util.regex.*;
class Adv2{
public static void main(String[] a){
Pattern p = Pattern.compile("^(?s).*$"); // ^ и $ + DOTALL включен через (?s)
String s = "line1\nline2";
System.out.println(p.matcher(s).matches()); // true - точка покрывает перевод строки
}
}
true
// Advanced 3: валидация сложной структуры и извлечение групп при matches()
import java.util.regex.*;
class Adv3{
public static void main(String[] a){
Pattern p = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
Matcher m = p.matcher("2026-04-22");
if(m.matches()){
System.out.println(m.group(1)); // год
System.out.println(m.group(2)); // месяц
System.out.println(m.group(3)); // день
}
}
}
2026 04 22
// Advanced 4: использование transparent bounds при вложенных регионах
import java.util.regex.*;
class Adv4{
public static void main(String[] a){
Pattern p = Pattern.compile("^A.*Z$");
Matcher m = p.matcher("XAXYZPZ");
m.region(1, 6); // регион: "AXYZP"
m.useTransparentBounds(true);
System.out.println(m.matches()); // false - шаблон требует начало A и конец Z внутри региона
}
}
false
// Advanced 5: проверка больших потоков без перекомпиляции шаблона
import java.util.regex.*;
class Adv5{
public static void main(String[] a){
Pattern p = Pattern.compile("[A-Za-z0-9_]+@[A-Za-z0-9_.-]+\\.[A-Za-z]{2,}");
String[] emails = {"user@example.com","bad email","admin@site.ru"};
Matcher m = p.matcher("");
for(String e: emails){
m.reset(e);
System.out.println(e + " -> " + m.matches());
}
}
}
user@example.com -> true bad email -> false admin@site.ru -> true
Пояснения: использование region позволяет проверять подстроки без извлечения новой строки; reset обновляет содержимое у уже созданного Matcher, что выгодно по производительности; группы доступны после успешного вызова matches().