Главная/Статьи/Полезные регулярные выражения: справочник паттернов

Полезные регулярные выражения: справочник паттернов

Коллекция проверенных регулярных выражений для валидации email, телефонов, дат, URL, IP-адресов и других данных. С примерами на PHP и JavaScript.

ДМ
Дмитрий Мещеряков
📅 26 января 2024 г.📖 5 мин чтения

Подборка шаблонов, к которым я возвращаюсь чаще всего. Пользоваться ими стоит с одной оговоркой, и лучше проговорить её сразу: регулярное выражение проверяет форму, а не смысл. Строка, прошедшая проверку на email, не означает существующий адрес; совпавшее с шаблоном число не означает корректный телефон.

Отсюда практическое правило, экономящее много времени: регулярка хороша для отсечения явного мусора и для извлечения данных из текста. Как единственный способ валидации она подводит почти всегда — и чем сложнее формат, тем раньше.

Числа и идентификаторы

Только цифры

regex
# Начиная с 1 (без ведущих нулей)
^[1-9]+[0-9]*$

# С возможным ведущим нулём
^[0-9]+$

# Целые числа (включая отрицательные)
^-?\d+$

# Числа с плавающей точкой
^-?\d+(\.\d+)?$

UUID

regex
^[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 перестанут быть разными значениями.

Email

regex
# Базовая проверка
^[\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.

Телефоны

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

regex
# HTTP/HTTPS
^https?:\/\/[^\s/$.?#].[^\s]*$

# С поддержкой ftp, telnet
^(https?|ftp|telnet):\/\/[^\s/$.?#].[^\s]*$

Домен

regex
^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$

IP-адреса

regex
# 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-адрес

regex
^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$

Примеры: 00:1A:2B:3C:4D:5E, 00-1A-2B-3C-4D-5E

Даты и время

Даты

regex
# 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}$

Время

regex
# 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)$

Пароли и безопасность

Надёжный пароль

regex
# Минимум 8 символов, буквы и цифры
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$

# Минимум 8 символов, буквы, цифры и спецсимволы
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$

Имя пользователя

regex
# 3-20 символов, латиница, цифры, _, -
^[a-zA-Z][a-zA-Z0-9_-]{2,19}$

Текст и имена

ФИО (кириллица)

regex
^[а-яА-ЯёЁ]+\s+[а-яА-ЯёЁ]+(\s+[а-яА-ЯёЁ]+)?$

Только буквы и цифры

regex
# Латиница
^[a-zA-Z0-9]+$

# Кириллица + латиница
^[а-яА-ЯёЁa-zA-Z0-9]+$

Финансы

Номер банковской карты

regex
# 13-19 цифр
^\d{13,19}$

# С разделителями (пробелы или дефисы)
^(\d{4}[\s-]?){3}\d{1,7}$

Сумма денег

regex
# С точкой или запятой
^\d+([.,]\d{1,2})?$

Примеры использования

PHP

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

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
uUnicode (PHP)/\p{L}+/u

Три вещи, о которых стоит помнить

Катастрофический откат — реальный способ положить сервер. Выражения с вложенными квантификаторами вида (a+)+ на неудачной входной строке заставляют движок перебирать экспоненциальное число вариантов: сотня символов может выполняться минутами и занимать процесс целиком. Если регулярка применяется к данным от пользователя, это превращается в отказ в обслуживании одним запросом.

Практическая защита: избегайте вложенных квантификаторов, ограничивайте длину входной строки перед проверкой и задавайте в PHP разумный pcre.backtrack_limit. И проверяйте сложные выражения не только на правильных данных, но и на длинных почти-подходящих — именно они дают худший случай.

Флаг u в PHP обязателен для кириллицы. Без него . и классы символов работают с байтами, а не с символами, и на UTF-8 это даёт разрезанные посередине буквы и неверную длину. Забытый u — самая частая причина «регулярка работает на латинице и ломается на русском».

Читаемость важнее краткости. Выражение, которое нельзя понять через полгода, придётся переписать целиком — а значит, заново отладить. Флаг x в PHP позволяет разбить регулярку на строки с комментариями; для чего-то сложнее пары групп это окупается сразу.

💡 Совет

И общий совет: разбор структурированных форматов регулярками — плохая идея. HTML, JSON, XML, CSV имеют вложенность и экранирование, которые регулярные выражения выразить не могут. Для каждого из них есть парсер, и он и надёжнее, и обычно быстрее. Регулярка по HTML работает на примерах из статьи и ломается на реальной странице.

🚀

Хотите такое же решение?

Настрою окружение под ваш проект, учту специфику инфраструктуры и обучу команду.

Обсудить проект →
Бесплатная консультация · Ответ в течение дня

Комментарии

Система комментариев скоро будет подключена. А пока вы можете написать мне в Telegram или на email.