Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Практическая валидация
practical_validation

Практическая валидация

Валидация email, телефонов, URL, дат, паролей и других форматов

Практическая валидация

Регулярные выражения широко используются для валидации данных: email, телефоны, URL, даты, пароли. В этой теме изучим практические паттерны для распространённых форматов.

#Валидация email

#Простой паттерн

import re # Базовая валидация email pattern = r'^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}$' def is_valid_email(email): return bool(re.match(pattern, email)) is_valid_email('user@example.com') # True is_valid_email('user.name@example.com') # True is_valid_email('user@sub.example.co.uk') # True is_valid_email('invalid') # False is_valid_email('user@') # False

#Более строгий паттерн

# Без точек в начале/конце, без последовательных точек pattern = r'^(?!.*\.\.)[\w.-]+[\w-]@[\w.-]+\.[a-zA-Z]{2,}$' # (?!. *\.\.) — нет последовательных точек # [\w.-]+[\w-] — не заканчивается на точку перед @

#С lookahead для сложных правил

# Минимум 8 символов, есть буква и цифра pattern = r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$'

#Валидация телефона

#Российский телефон

# +7 и 10 цифр pattern = r'^\+7\d{10}$' is_valid_phone('+79991234567') # True is_valid_phone('+70000000000') # True is_valid_phone('89991234567') # False — начинается с 8

#С форматированием

# Разные форматы: +7 (999) 123-45-67, +7-999-123-45-67 pattern = r'^\+7[\s()\-0-9]{10,}$' # Более строгий: конкретные форматы pattern = r'^\+7\s?\(?\d{3}\)?[\s\-]?\d{3}[\s\-]?\d{2}[\s\-]?\d{2}$' is_valid('+7 (999) 123-45-67') # True is_valid('+79991234567') # True is_valid('+7-999-123-45-67') # True

#Универсальный международный формат

# E.164 формат: + и 7-15 цифр pattern = r'^\+\d{7,15}$' is_valid('+1234567890') # True is_valid('+79991234567') # True is_valid('+442071234567') # True

#Валидация URL

#Простой паттерн

# http/https домен и путь pattern = r'^https?://[\w.-]+(?:/[\w./-]*)?$' is_valid_url('https://example.com') # True is_valid_url('http://example.com/path') # True is_valid_url('ftp://example.com') # False — нет ftp

#С поддоменами и портом

pattern = r'^https?://(?:[\w-]+\.)+[\w-]+(?::\d+)?(?:/[\w./-]*)?$' # (?:[\w-]+\.)+ — один или более поддоменов # [\w-]+ — домен верхнего уровня # (?::\d+)? — опциональный порт # (?:/[\w./-]*)? — опциональный путь is_valid('https://www.example.com') # True is_valid('https://sub.example.com:8080') # True is_valid('https://example.com/path/page') # True

#Полный паттерн с query string

pattern = r''' ^https?:// # протокол (?:[\w-]+\.)+[\w-]+ # домен (?::\d+)? # порт (?:/[\w./-]*)? # путь (?:\?[^\s#]*)? # query string (?:#[^\s]*)? # fragment $ ''' re.compile(pattern, re.VERBOSE)

#Валидация даты

#Формат YYYY-MM-DD

pattern = r'^\d{4}-\d{2}-\d{2}$' is_valid_date('2024-03-09') # True is_valid_date('2024-3-9') # False — нужны ведущие нули

#С проверкой диапазона

# Год 1900-2099, месяц 01-12, день 01-31 pattern = r'^(19|20)\d{2}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$' # (19|20)\d{2} — год 1900-2099 # (0[1-9]|1[0-2]) — месяц 01-12 # (0[1-9]|[12]\d|3[01]) — день 01-31 is_valid('2024-03-09') # True is_valid('2024-13-01') # False — месяц 13 is_valid('2024-02-30') # True по regex, но неверная дата

Примечание: Regex не может проверить корректность даты (30 февраля, 31 апреля). Для полной валидации используйте datetime.

#Формат DD.MM.YYYY

pattern = r'^(0[1-9]|[12]\d|3[01])\.(0[1-9]|1[0-2])\.(19|20)\d{2}$' is_valid('09.03.2024') # True is_valid('31.04.2024') # True по regex, но неверная дата

#Валидация пароля

#Базовые требования

# Минимум 8 символов pattern = r'^.{8,}$' is_valid('password') # True is_valid('pass') # False

#Буквы и цифры

# Минимум 8 символов, хотя бы одна буква и одна цифра pattern = r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$' # (?=.*[A-Za-z]) — есть буква # (?=.*\d) — есть цифра # [A-Za-z\d]{8,} — только буквы и цифры, минимум 8 is_valid('password1') # True is_valid('password') # False — нет цифры is_valid('12345678') # False — нет буквы

#Со спецсимволами

# Минимум 8 символов, буква, цифра, спецсимвол pattern = r'^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$' is_valid('Pass123!') # True is_valid('Password1') # False — нет спецсимвола

#Сложный пароль

# 8-20 символов, заглавная, строчная, цифра, спецсимвол pattern = r''' ^ (?=.*[a-z]) # хотя бы одна строчная (?=.*[A-Z]) # хотя бы одна заглавная (?=.*\d) # хотя бы одна цифра (?=.*[@$!%*?&]) # хотя бы один спецсимвол [A-Za-z\d@$!%*?&]{8,20} $ ''' re.compile(pattern, re.VERBOSE)

#Валидация IP-адреса

#IPv4

# 0-255.0-255.0-255.0-255 pattern = r'^(\d{1,3}\.){3}\d{1,3}$' # Более строгий: проверка диапазона 0-255 pattern = r''' ^ (25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\. (25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\. (25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\. (25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d) $ ''' # 25[0-5] — 250-255 # 2[0-4]\d — 200-249 # 1\d{2} — 100-199 # [1-9]?\d — 0-99 is_valid('192.168.1.1') # True is_valid('255.255.255.255') # True is_valid('256.1.1.1') # False

#IPv6 (упрощённый)

# 8 групп по 4 hex-символа pattern = r'^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$' is_valid('2001:0db8:85a3:0000:0000:8a2e:0370:7334') # True

#Валидация кредитной карты

#Простой паттерн

# 16 цифр, возможно с пробелами или дефисами pattern = r'^\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}$' is_valid('1234567890123456') # True is_valid('1234-5678-9012-3456') # True is_valid('1234 5678 9012 3456') # True

#С проверкой Luhn (только формат)

# Regex проверяет только формат, не алгоритм Luhn pattern = r'^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13})$' # 4... — Visa # 5[1-5]... — MasterCard # 3[47]... — American Express

#Валидация HEX-цвета

# #RGB, #RRGGBB pattern = r'^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$' is_valid('#FFF') # True is_valid('#FFFFFF') # True is_valid('#ff5733') # True is_valid('FFF') # False — нет # is_valid('#GGGGGG') # False — G не hex

#Практические примеры

#1. Комплексная валидация формы

class FormValidator: EMAIL_PATTERN = re.compile(r'^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}$') PHONE_PATTERN = re.compile(r'^\+7\d{10}$') PASSWORD_PATTERN = re.compile(r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$') @staticmethod def validate_email(email): return bool(FormValidator.EMAIL_PATTERN.match(email)) @staticmethod def validate_phone(phone): return bool(FormValidator.PHONE_PATTERN.match(phone.replace(' ', '').replace('-', ''))) @staticmethod def validate_password(password): return bool(FormValidator.PASSWORD_PATTERN.match(password))

#2. Валидация с сообщением об ошибке

def validate_password(password): errors = [] if len(password) < 8: errors.append('Минимум 8 символов') if not re.search(r'[A-Za-z]', password): errors.append('Хотя бы одна буква') if not re.search(r'\d', password): errors.append('Хотя бы одна цифра') if not re.search(r'[@$!%*?&]', password): errors.append('Хотя бы один спецсимвол') return len(errors) == 0, errors valid, errors = validate_password('pass') # False, ['Минимум 8 символов', 'Хотя бы одна цифра', 'Хотя бы один спецсимвол']

#Распространённые ошибки

#1. Слишком строгий паттерн

# Ошибка: не учитывает поддомены pattern = r'^[\w]+@[\w]+\.[a-zA-Z]{2,}$' # Несоответствует: user@sub.example.com # Правильно: r'^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}$'

#2. Слишком слабый паттерн

# Ошибка:соответствует что угодно pattern = r'.+@.+\..+' #соответствует: @., a@b.c # Правильно: r'^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}$'

#3. Regex для полной валидации даты

# Ошибка: regex не может проверить 30 февраля pattern = r'^\d{4}-02-(30|31)$' # Всё равносоответствует # Правильно: использовать datetime from datetime import datetime try: datetime.strptime('2024-02-30', '%Y-%m-%d') except ValueError: print('Неверная дата')

Далее: Практический парсинг