Подборка шаблонов, к которым я возвращаюсь чаще всего. Пользоваться ими стоит с одной оговоркой, и лучше проговорить её сразу: регулярное выражение проверяет форму, а не смысл. Строка, прошедшая проверку на email, не означает существующий адрес; совпавшее с шаблоном число не означает корректный телефон.
Отсюда практическое правило, экономящее много времени: регулярка хороша для отсечения явного мусора и для извлечения данных из текста. Как единственный способ валидации она подводит почти всегда — и чем сложнее формат, тем раньше.
Числа и идентификаторы
Только цифры
# Начиная с 1 (без ведущих нулей)
^[1-9]+[0-9]*$
# С возможным ведущим нулём
^[0-9]+$
# Целые числа (включая отрицательные)
^-?\d+$
# Числа с плавающей точкой
^-?\d+(\.\d+)?$UUID
^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$Пример: 550e8400-e29b-41d4-a716-446655440000
Контактные данные
Для email и URL не пишите свою регулярку. Оба формата описаны стандартами, которые сложнее любого разумного выражения, и в PHP для них есть встроенные проверки: filter_var($value, FILTER_VALIDATE_EMAIL) и FILTER_VALIDATE_URL. Шаблоны ниже полезны, чтобы найти адреса в тексте, но не чтобы решить, валиден ли введённый пользователем.
С телефонами история другая: единого формата не существует, и регулярка здесь как раз уместна — но как отсечение мусора, а не как гарантия. Практичнее сначала нормализовать (оставить цифры, привести к единому виду), а потом проверять длину и префикс: так +7 (999) 123-45-67 и 89991234567 перестанут быть разными значениями.
# Базовая проверка
^[\w.-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$
# Более строгая (RFC 5322 упрощённая)
^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$Рекомендация: Для валидации email в PHP используйте filter_var($email, FILTER_VALIDATE_EMAIL) — это надёжнее самописных regex.
Телефоны
# Россия (+7, 8)
^(\+7|7|8)[0-9]{10}$
# Универсальный международный
^(\+)?[0-9]{1,4}[\s-]?(\([0-9]{1,3}\)[\s-]?)?[0-9]{1,4}[\s-]?[0-9]{1,4}[\s-]?[0-9]{1,9}$
# Мобильный РФ с форматированием
^(\+7|8)[\s-]?\(?9[0-9]{2}\)?[\s-]?[0-9]{3}[\s-]?[0-9]{2}[\s-]?[0-9]{2}$Сеть и URL
URL
# HTTP/HTTPS
^https?:\/\/[^\s/$.?#].[^\s]*$
# С поддержкой ftp, telnet
^(https?|ftp|telnet):\/\/[^\s/$.?#].[^\s]*$Домен
^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$IP-адреса
# IPv4
^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$
# IPv6 (упрощённый)
^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$
# IPv4 или IPv6
^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$MAC-адрес
^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$Примеры: 00:1A:2B:3C:4D:5E, 00-1A-2B-3C-4D-5E
Даты и время
Даты
# YYYY-MM-DD
^\d{4}-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$
# DD.MM.YYYY (российский формат)
^(0[1-9]|[12]\d|3[01])\.(0[1-9]|1[012])\.(19|20)\d{2}$
# DD/MM/YYYY
^(0[1-9]|[12]\d|3[01])/(0[1-9]|1[012])/(19|20)\d{2}$Время
# HH:MM:SS (24-часовой формат)
^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$
# HH:MM (без секунд)
^([01]\d|2[0-3]):([0-5]\d)$
# 12-часовой формат с AM/PM
^(0?[1-9]|1[0-2]):[0-5]\d\s?(AM|PM|am|pm)$Пароли и безопасность
Надёжный пароль
# Минимум 8 символов, буквы и цифры
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$
# Минимум 8 символов, буквы, цифры и спецсимволы
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$Имя пользователя
# 3-20 символов, латиница, цифры, _, -
^[a-zA-Z][a-zA-Z0-9_-]{2,19}$Текст и имена
ФИО (кириллица)
^[а-яА-ЯёЁ]+\s+[а-яА-ЯёЁ]+(\s+[а-яА-ЯёЁ]+)?$Только буквы и цифры
# Латиница
^[a-zA-Z0-9]+$
# Кириллица + латиница
^[а-яА-ЯёЁa-zA-Z0-9]+$Финансы
Номер банковской карты
# 13-19 цифр
^\d{13,19}$
# С разделителями (пробелы или дефисы)
^(\d{4}[\s-]?){3}\d{1,7}$Сумма денег
# С точкой или запятой
^\d+([.,]\d{1,2})?$Примеры использования
PHP
<?php
class Validator
{
private const PATTERNS = [
'email' => '/^[\w.-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/',
'phone_ru' => '/^(\+7|7|8)[0-9]{10}$/',
'date_iso' => '/^\d{4}-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$/',
'uuid' => '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i',
];
public static function validate(string $type, string $value): bool
{
if (!isset(self::PATTERNS[$type])) {
throw new \InvalidArgumentException("Unknown pattern: {$type}");
}
return (bool) preg_match(self::PATTERNS[$type], $value);
}
public static function isEmail(string $value): bool
{
// Рекомендуемый способ для email
return filter_var($value, FILTER_VALIDATE_EMAIL) !== false;
}
public static function isPhoneRu(string $value): bool
{
// Очищаем от пробелов и скобок
$clean = preg_replace('/[\s()-]/', '', $value);
return self::validate('phone_ru', $clean);
}
public static function extractEmails(string $text): array
{
preg_match_all('/[\w.-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/', $text, $matches);
return $matches[0] ?? [];
}
public static function extractPhones(string $text): array
{
preg_match_all('/(\+7|8)[\s-]?\(?9\d{2}\)?[\s-]?\d{3}[\s-]?\d{2}[\s-]?\d{2}/', $text, $matches);
return $matches[0] ?? [];
}
}
// Использование
$email = 'user@example.com';
var_dump(Validator::isEmail($email)); // true
$phone = '+7 (999) 123-45-67';
var_dump(Validator::isPhoneRu($phone)); // true
$text = 'Контакты: mail@test.ru, +7 999 123 45 67';
print_r(Validator::extractEmails($text)); // ['mail@test.ru']
print_r(Validator::extractPhones($text)); // ['+7 999 123 45 67']JavaScript
const patterns = {
email: /^[\w.-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/,
phoneRu: /^(\+7|7|8)[0-9]{10}$/,
dateIso: /^\d{4}-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$/,
uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
url: /^https?:\/\/[^\s/$.?#].[^\s]*$/,
};
function validate(type, value) {
if (!patterns[type]) {
throw new Error(`Unknown pattern: ${type}`);
}
return patterns[type].test(value);
}
function cleanPhone(phone) {
return phone.replace(/[\s()\-]/g, '');
}
// Использование
console.log(validate('email', 'user@example.com')); // true
console.log(validate('phoneRu', cleanPhone('+7 (999) 123-45-67'))); // true
console.log(validate('url', 'https://example.com/path')); // true
// Извлечение данных
const text = 'Пишите на mail@test.ru или звоните +7 999 123 45 67';
const emails = text.match(/[\w.-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g);
console.log(emails); // ['mail@test.ru']Таблица модификаторов
| Модификатор | Описание | Пример |
|---|---|---|
i | Без учёта регистра | /hello/i |
g | Глобальный поиск (JS) | /\d+/g |
m | Многострочный режим | /^start/m |
s | Точка включает \n | /a.b/s |
u | Unicode (PHP) | /\p{L}+/u |
Три вещи, о которых стоит помнить
Катастрофический откат — реальный способ положить сервер. Выражения с вложенными квантификаторами вида (a+)+ на неудачной входной строке заставляют движок перебирать экспоненциальное число вариантов: сотня символов может выполняться минутами и занимать процесс целиком. Если регулярка применяется к данным от пользователя, это превращается в отказ в обслуживании одним запросом.
Практическая защита: избегайте вложенных квантификаторов, ограничивайте длину входной строки перед проверкой и задавайте в PHP разумный pcre.backtrack_limit. И проверяйте сложные выражения не только на правильных данных, но и на длинных почти-подходящих — именно они дают худший случай.
Флаг u в PHP обязателен для кириллицы. Без него . и классы символов работают с байтами, а не с символами, и на UTF-8 это даёт разрезанные посередине буквы и неверную длину. Забытый u — самая частая причина «регулярка работает на латинице и ломается на русском».
Читаемость важнее краткости. Выражение, которое нельзя понять через полгода, придётся переписать целиком — а значит, заново отладить. Флаг x в PHP позволяет разбить регулярку на строки с комментариями; для чего-то сложнее пары групп это окупается сразу.
И общий совет: разбор структурированных форматов регулярками — плохая идея. HTML, JSON, XML, CSV имеют вложенность и экранирование, которые регулярные выражения выразить не могут. Для каждого из них есть парсер, и он и надёжнее, и обычно быстрее. Регулярка по HTML работает на примерах из статьи и ломается на реальной странице.
Комментарии
Система комментариев скоро будет подключена. А пока вы можете написать мне в Telegram или на email.