Добавить в корзинуПозвонить
Найти в Дзене
Программирование

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

Мне нужно было вытащить email из логов. Открыл ChatGPT: "дай regex для email на Питоне". Секунда - получил строчку: [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,} Скопировал, запустил. Что-то нашло. Окей, вроде работает.
Через день коллега спросил: почему половина адресов пропала из выгрузки? Обычные адреса, ничего странного. Паттерн их просто не увидел.
Я уставился на эту строчку. Правильная она? Понятия не имел. Проверить как - тоже. Там проблема и началась. Регулярное выражение - шаблон для поиска в тексте. Пишешь что ищешь, Питон находит. import re
text = "купил хлеб и ещё хлеб" result = re.findall("хлеб", text) print(result)
Результат: ['хлеб', 'хлеб'] Слово "хлеб" - уже регулярка. Но regex умеет описывать не только точный текст, а целые классы символов. Цифры вообще, буквы вообще, повторения, позиции.
Разберём тот паттерн из ChatGPT по кусочкам. [abc] Скобки означают: подойдёт любой символ из этого списка. [abc] найдёт a или b или c. [a-z] Диапазон через дефис.
Оглавление

Мне нужно было вытащить email из логов. Открыл ChatGPT: "дай regex для email на Питоне". Секунда - получил строчку:

[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}

Скопировал, запустил. Что-то нашло. Окей, вроде работает.

Через день коллега спросил: почему половина адресов пропала из выгрузки? Обычные адреса, ничего странного. Паттерн их просто не увидел.

Я уставился на эту строчку. Правильная она? Понятия не имел. Проверить как - тоже. Там проблема и началась.

ЧТО ТАКОЕ REGEX ЗА 30 СЕКУНД

Регулярное выражение - шаблон для поиска в тексте. Пишешь что ищешь, Питон находит.

import re

text = "купил хлеб и ещё хлеб" result = re.findall("хлеб", text) print(result)

Результат: ['хлеб', 'хлеб']

Слово "хлеб" - уже регулярка. Но regex умеет описывать не только точный текст, а целые классы символов. Цифры вообще, буквы вообще, повторения, позиции.

Разберём тот паттерн из ChatGPT по кусочкам.


КВАДРАТНЫЕ СКОБКИ - ЛЮБОЙ ИЗ НАБОРА

[abc]

Скобки означают: подойдёт любой символ из этого списка. [abc] найдёт a или b или c.

[a-z]

Диапазон через дефис. [a-z] - любая строчная буква от a до z. [0-9] - любая цифра.

В паттерне для email первый кусок:

[a-zA-Z0-9._%+-]+

Что здесь:

  • a-z - строчные буквы
  • A-Z - заглавные
  • 0-9 - цифры
  • . _ % + - - эти символы просто как есть

Плюс после скобки значит "один или больше таких подряд".

Весь блок читается: последовательность букв/цифр/спецсимволов длиной от одного символа. Это часть до собаки в email.

ТОЧКА - ХИТРЫЙ СИМВОЛ

В обычном тексте точка просто точка. В regex точка означает "вообще любой символ". a.c найдёт abc, a5c, a_c - любой символ между a и c.

Хочешь именно точку - ставь обратный слеш:
\.

В паттерне email есть кусок
. - это именно точка перед доменной зоной. Без слеша он нашёл бы gmail_com так же как gmail.com.

ЖАДНОСТЬ

Квантификаторы + и * жадные. Берут максимум возможного.

Смотри:

<b>слово</b> текст <b>ещё</b>

Паттерн <.+> - "открывающая скобка, любые символы, закрывающая".

import re

text = "<b>слово</b> текст <b>ещё</b>" print(re.findall("<.+>", text))

Результат: ['<b>слово</b> текст <b>ещё</b>']

Нашло всё от первой
< до последней >. Квантификатор жадный - сожрал сколько влезло.

Добавляешь вопросительный знак и
+ становится ленивым:

print(re.findall("<.+?>", text))

Результат: ['<b>', '</b>', '<b>', '</b>']

Теперь останавливается на первой же
>. Один символ изменил всё поведение.

Это объясняет половину случаев "почему оно нашло фигню".

РЕАЛЬНЫЙ ПРИМЕР: ВЫТАЩИТЬ СУММЫ ИЗ ЖАЛОБ

Работал с отзывами на товары. Надо было найти упоминания денег. "Заплатил 3000", "стоит 1500р", "отдал двадцать тысяч" - форматы разные.

import re
text = "Заплатил 3000 руб за ерунду. Видел за 1500р - жадность. Отдал 25000₽ вообще"
prices = re.findall(r"\d+\s?(?:руб|р|₽)", text)
print(prices)

Результат: ['3000 руб', '1500р', '25000₽']

Что тут:

  • \d - любая цифра
  • \d+ - одна или больше цифр подряд
  • \s? - может быть пробел, может нет (вопросительный знак - ноль или один)
  • руб|р|₽ - вертикальная черта означает "или"

Читается: цифры, возможно пробел, потом руб или р или значок рубля. Без regex писал бы split, циклы, if-ы на страницу кода. Тут - всего одна строчка.

Когда regex лишний

Ищешь точное слово - используй "слово" in text. Быстрее и проще. Проверяешь начало строки - text.startswith("префикс"). Простая замена - text.replace("старое", "новое"). Regex хорош там, где структура повторяется, а детали меняются. Даты, номера, коды, извлечение чисел, чистка текста.

Как я использую ChatGPT сейчас

Нейросети могут галлюцинировать и не всегда давать идеальный ответ, даже если ты написал хороший промт. Я разобрался с regex нормально, перелопатил всю документацию. Иногда проверяю свои паттерны через ИИ, когда он даёт паттерн - я читаю его за секунды. Вижу что он делает, где споткнётся. Правлю под свои данные сразу. Но в основных код пишу сам.

Раньше копировал вслепую. Работает - хорошо, сломалось - в гугл. Сейчас контролирую процесс.

Вот разница между "надеюсь сработает" и "знаю что будет".

Всё что показал выше хватит на большинство стандартных задач. Остальное - lookahead/lookbehind, именованные группы, флаги, оптимизация - уже продвинутые штуки.

Не так давно я опубликовал курс по regex в Питоне. 72 урока, более 900 тестов и задач с автопроверкой. От базы до сложных конструкций. Текстовый формат: урок 15 минут, задачи, закрыл. Рекомендую всем, кто хочет прокачать свои навыки, пройти любой собес и удивить своих коллег.

👉 Регулярные выражения (Regex) в Python: Интерактивный тренажёр