🐛 Типичные ошибки

⚡ Топ-5 ошибок

  1. Забыть r"..." перед регулярным выражением.
  2. Использовать жадный квантификатор там, где нужен ленивый.
  3. Путать re.match и re.search.
  4. Изменять внешнюю переменную без nonlocal.
  5. «Позднее связывание» в циклах.

❌ Ошибка 1. Забыта сырые строки

import re

pattern = "\d"  # DeprecationWarning или неожиданное поведение
print(re.findall(pattern, "Price: 123"))

Почему возникает: Python интерпретирует \d как управляющую последовательность ещё до того, как шаблон попадёт в re. В некоторых случаях получится символ, который регулярное выражение не поймёт.

✅ Исправление

import re

pattern = r"\d"
print(re.findall(pattern, "Price: 123"))  # ['1', '2', '3']

❌ Ошибка 2. Жадный квантификатор захватывает лишнее

import re

text = "<div>Hello</div><div>World</div>"
print(re.findall(r"<.*>", text))
# ['<div>Hello</div><div>World</div>']

Почему возникает: * по умолчанию жадный и тянет до последнего > в строке.

✅ Исправление

import re

text = "<div>Hello</div><div>World</div>"
print(re.findall(r"<.*?>", text))
# ['<div>', '</div>', '<div>', '</div>']

❌ Ошибка 3. Путаница re.match и re.search

import re

text = "Order ID: 12345"
match = re.match(r"\d+", text)
print(match)  # None

Почему возникает: re.match проверяет совпадение только в начале строки. Цифры находятся не в начале.

✅ Исправление

import re

text = "Order ID: 12345"
match = re.search(r"\d+", text)
print(match.group())  # 12345

❌ Ошибка 4. Изменение внешней переменной без nonlocal

def make_counter():
    count = 0

    def increment():
        count += 1  # UnboundLocalError
        return count

    return increment

Сообщение об ошибке: UnboundLocalError: cannot access local variable 'count' where it is not associated with a value

Почему возникает: присваивание count += 1 делает count локальной для increment, но значение ещё не определено.

✅ Исправление

def make_counter():
    count = 0

    def increment():
        nonlocal count
        count += 1
        return count

    return increment

❌ Ошибка 5. Позднее связывание в цикле

def make_multipliers():
    return [lambda x: x * i for i in range(5)]


for func in make_multipliers():
    print(func(2))  # 8 8 8 8 8

Почему возникает: лямбда захватывает имя i, а не его значение. К моменту вызова цикл уже закончился, и i == 4.

✅ Исправление

def make_multipliers():
    return [lambda x, i=i: x * i for i in range(5)]


for func in make_multipliers():
    print(func(2))  # 0 2 4 6 8

❌ Ошибка 6. Пропущены скобки в декораторе

def my_decorator(func):
    def wrapper:  # SyntaxError
        print("До")
        func()
        print("После")
    return wrapper

Почему возникает: определение функции всегда требует круглых скобок, даже если параметров нет.

✅ Исправление

def my_decorator(func):
    def wrapper():
        print("До")
        func()
        print("После")
    return wrapper