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, но будет false
    false
  • Регулярное выражение без якорей воспринимается как шаблон для части строки в некоторых языках, но в 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 и улучшения производительности в реализации движка регулярных выражений. Поведение якорей, флагов и регионов осталось совместимым с существующими спецификациями, поэтому старые примеры обычно продолжают работать без изменений.

Расширенные и редкие сценарии применения

Ниже несколько более сложных случаев с пояснениями.

Пример java
// 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
Пример java
// 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
Пример java
// 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
Пример java
// 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
Пример java
// 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().

джава Matcher.matches() function comments

En
Matcher.matches() Проверяет соответствие строки шаблону