Регулярные выражения в Java с примерами: Полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Регулярные выражения в Java: от основ до продвинутого использования

Регулярные выражения (regex) — это мощный инструмент для работы с текстом, позволяющий выполнять поиск, замену и проверку строк по сложным шаблонам. В Java поддержка регулярных выражений реализована через пакет java.util.regex, который предоставляет два основных класса: Pattern (компилирует шаблон) и Matcher (выполняет операции поиска/замены).

В этой статье мы разберем, как эффективно использовать регулярные выражения в Java, начиная с базового синтаксиса и заканчивая реальными примерами из практики разработки.

1. Основы синтаксиса регулярных выражений в Java

Прежде чем переходить к Java-коду, важно освоить основные метасимволы регулярных выражений:

  • . — любой одиночный символ (кроме перевода строки)
  • \d — любая цифра (0-9)
  • \w — буква, цифра или подчеркивание
  • \s — пробельный символ (пробел, табуляция, новая строка)
  • * — 0 или более повторений предыдущего символа
  • + — 1 или более повторений
  • ? — 0 или 1 повторение (делает символ опциональным)
  • ^ — начало строки
  • $ — конец строки
  • [...] — символьный класс (например, [a-z] — все строчные буквы)
  • (...) — группа захвата

Важно: В Java строки с регулярными выражениями требуют двойного экранирования. Например, чтобы использовать \d, в коде пишем "\\d". Это связано с тем, что обратная косая черта сначала обрабатывается компилятором Java, а затем передается движку regex.

2. Классы Pattern и Matcher — основа работы с regex в Java

Базовая схема работы с регулярными выражениями в Java состоит из трех шагов:

  1. Создание объекта Pattern путем компиляции строки шаблона
  2. Создание объекта Matcher путем вызова метода matcher() на строке, которую нужно проверить
  3. Выполнение операций — поиск, совпадение, замена

Пример 1: Проверка соответствия всей строки

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class RegexExample {
    public static void main(String[] args) {
        // Проверка, является ли строка корректным email-адресом
        String email = "user@example.com";
        String emailPattern = "^[A-Za-z0-9+_.-]+@(.+)$";
        
        Pattern pattern = Pattern.compile(emailPattern);
        Matcher matcher = pattern.matcher(email);
        
        if (matcher.matches()) {
            System.out.println("Email корректен");
        } else {
            System.out.println("Email некорректен");
        }
    }
}

Метод matches() пытается сопоставить шаблон со всей строкой целиком. Если нужно проверить, содержит ли строка совпадение с шаблоном (не обязательно полностью), используется метод find().

Пример 2: Поиск всех вхождений шаблона в строке

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class FindExample {
    public static void main(String[] args) {
        String text = "Java 8, Java 11, Java 17 — это версии языка Java";
        String regex = "Java\\s+\\d+";
        
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);
        
        while (matcher.find()) {
            System.out.println("Найдено: " + matcher.group() + 
                               " (позиция: " + matcher.start() + "-" + matcher.end() + ")");
        }
    }
}

Результат выполнения:

Найдено: Java 8 (позиция: 0-6)
Найдено: Java 11 (позиция: 8-15)
Найдено: Java 17 (позиция: 17-24)

3. Практические примеры: валидация и извлечение данных

Рассмотрим наиболее востребованные сценарии использования регулярных выражений в Java-разработке.

Пример 3: Валидация номера телефона

public class PhoneValidator {
    public static boolean isValidPhone(String phone) {
        // Формат: +7 (XXX) XXX-XX-XX или 8 (XXX) XXX-XX-XX
        String regex = "^(\\+7|8)\\s?\\(?\\d{3}\\)?\\s?\\d{3}\\-?\\d{2}\\-?\\d{2}$";
        return Pattern.matches(regex, phone);
    }
    
    public static void main(String[] args) {
        System.out.println(isValidPhone("+7 (123) 456-78-90")); // true
        System.out.println(isValidPhone("8(999)1234567"));     // true
        System.out.println(isValidPhone("+71234567890"));      // true
        System.out.println(isValidPhone("123-45-67"));         // false
    }
}

Пример 4: Извлечение всех URL из текста

import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.ArrayList;
import java.util.List;

public class UrlExtractor {
    public static List<String> extractUrls(String text) {
        String regex = "https?://[\\w./?=&%-]+";
        List<String> urls = new ArrayList<>();
        
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);
        
        while (matcher.find()) {
            urls.add(matcher.group());
        }
        return urls;
    }
    
    public static void main(String[] args) {
        String text = "Посетите https://pythonlib.ru и http://example.com для обучения";
        List<String> urls = extractUrls(text);
        urls.forEach(System.out::println);
    }
}

Пример 5: Замена с использованием групп захвата

Группы захвата позволяют не только найти, но и переиспользовать части совпадения при замене.

public class RegexReplace {
    public static void main(String[] args) {
        String text = "Иванов Иван, Петров Петр, Сидоров Сидор";
        
        // Меняем местами фамилию и имя: "Фамилия Имя" → "Имя Фамилия"
        String regex = "(\\w+)\\s+(\\w+)";
        String replacement = "$2                

Блоги

Рекомендаций по книгам