Регулярные выражения в Java: полное руководство с примерами кода
Регулярные выражения (regex) — мощный инструмент для поиска, извлечения и замены текста по шаблону. В Java работа с регулярными выражениями реализована через два основных класса: java.util.regex.Pattern (компиляция шаблона) и java.util.regex.Matcher (выполнение поиска). В этой статье мы разберём синтаксис, основные методы и рассмотрим практические примеры, которые помогут вам уверенно использовать regex в реальных проектах.
1. Основы работы с регулярными выражениями в Java
Прежде чем перейти к примерам, давайте разберём ключевые классы и их взаимодействие.
Класс Pattern
Pattern — это скомпилированное представление регулярного выражения. Он создаётся статическим методом Pattern.compile(). Без компиляции использовать regex невозможно.
Класс Matcher
Matcher — это «движок», который выполняет поиск по заданному шаблону в строке. Создаётся методом pattern.matcher(inputString).
Базовый синтаксис метасимволов
.— любой символ (кроме перевода строки)\d— цифра (0-9)\w— буква, цифра или подчёркивание\s— пробельный символ^— начало строки$— конец строки*— 0 или более повторений+— 1 или более повторений?— 0 или 1 повторение{n,m}— от n до m повторений[]— набор символов (например,[a-z]— любая строчная буква)()— группа захвата
Пример 1: Простая проверка номера телефона
import java.util.regex.*;
public class PhoneValidator {
public static void main(String[] args) {
String phone = "+7 (999) 123-45-67";
String regex = "^\\+7\\s\\(\\d{3}\\)\\s\\d{3}-\\d{2}-\\d{2}$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(phone);
if (matcher.matches()) {
System.out.println("Номер корректный");
} else {
System.out.println("Номер не соответствует формату");
}
}
}
2. Методы Matcher: matches(), find() и группа захвата
Понимание разницы между matches() и find() — ключ к успешной работе с regex в Java.
matches()— проверяет, соответствует ли вся строка шаблону целиком (неявно добавляет^и$).find()— ищет подстроку, соответствующую шаблону, в любом месте строки.group()— возвращает найденное совпадение или значение группы захвата.
Пример 2: Извлечение email-адресов из текста с помощью find() и групп
import java.util.regex.*;
public class EmailExtractor {
public static void main(String[] args) {
String text = "Контакты: support@example.com, info@test.org и admin@site.net.";
String regex = "([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+)\\.([a-zA-Z]{2,})";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println("Полный email: " + matcher.group());
System.out.println("Имя пользователя: " + matcher.group(1));
System.out.println("Домен: " + matcher.group(2));
System.out.println("Зона: " + matcher.group(3));
System.out.println("---");
}
}
}
Пример 3: Валидация пароля с помощью matches()
Требования: от 8 до 20 символов, хотя бы одна заглавная буква, одна строчная, одна цифра и один спецсимвол.
import java.util.regex.*;
public class PasswordValidator {
public static boolean isValid(String password) {
String regex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>/?]).{8,20}$";
Pattern pattern = Pattern.compile(regex);
return pattern.matcher(password).matches();
}
public static void main(String[] args) {
String[] passwords = {"Weak1", "Strong@2024Pass", "short!A1"};
for (String pwd : passwords) {
System.out.println(pwd + " -> " + (isValid(pwd) ? "Корректный" : "Некорректный"));
}
}
}
3. Замена и разбиение строк с помощью regex
Класс String предоставляет удобные методы, которые внутри используют регулярные выражения.
Метод replaceAll()
Заменяет все подстроки, соответствующие шаблону, на указанную строку.
Пример 4: Маскировка номера кредитной карты
public class CardMasker {
public static void main(String[] args) {
String card = "1234 5678 9012 3456";
String masked = card.replaceAll("\\d(?=\\d{4})", "*");
System.out.println(masked); // **** **** **** 3456
}
}
Метод split()
Разбивает строку по регулярному выражению. Удобно для парсинга CSV, логов и т.д.
Пример 5: Разбор лога с разделителями
public class LogParser {
public static void main(String[] args) {
String log = "2024-01-15 14:30:00 [ERROR] Connection timeout";
String[] parts = log.split("\\s{2,}|\\[|\\]");
for (String part : parts) {
System.out.println("-> " + part.trim());
}
}
}
4. Практические кейсы: от простого к сложному
Кейс 1: Извлечение ссылок из HTML
import java.util.regex.*;
public class LinkExtractor {
public static void main(String[] args) {
String html = "<a href=\"https