Регулярные выражения в Python помогают находить подстроки по заданному правилу: цепочки букв, числа, повторяющиеся блоки и фрагменты выражений. При подготовке к ЕГЭ 2027 по информатике этот инструмент пригодится для обработки текста, в том числе в задании 24. Разберём синтаксис модуля re, проверим примеры и напишем программу для поиска самой длинной подходящей подстроки.
Регулярное выражение — шаблон, описывающий набор строк. Например, [0-9]+ означает последовательность из одной или нескольких цифр от 0 до 9. В Python поиск по такому шаблону выполняет стандартный модуль re.
import re
text = "Дата: 23-10-2026"
numbers = re.findall(r"[0-9]+", text)
print(numbers) # ['23', '10', '2026']
Функция findall вернула список строк. Если предстоит складывать найденные числа, сначала преобразуйте элементы через int.
Выбирайте функцию по задаче. Проверка выражения целиком отличается от поиска фрагмента внутри текста.
re.search(pattern, text) ищет первое совпадение в тексте.re.match(pattern, text) проверяет совпадение только с начала строки.re.fullmatch(pattern, text) проверяет, соответствует ли шаблону вся строка.re.findall(pattern, text) возвращает список неперекрывающихся совпадений или содержимого захватывающих групп.re.finditer(pattern, text) возвращает итератор объектов совпадения: у каждого доступны текст и позиции.re.sub(pattern, replacement, text) заменяет найденные фрагменты.re.split(pattern, text) разбивает строку по разделителям, заданным шаблоном.Если search, match или fullmatch ничего не нашли, результат равен None. Проверьте результат перед обращением к group(), иначе программа завершится с ошибкой.
| Запись | Значение |
|---|---|
[ABC] |
Одна буква A, B или C. |
[^ABC] |
Один символ, кроме A, B и C. |
[0-9] |
Одна цифра от 0 до 9. |
[A-Z] |
Одна заглавная латинская буква. |
. |
Любой символ, кроме перевода строки, при стандартных настройках. |
\d |
Десятичная цифра; для строк Python учитывает также цифры Unicode. |
\w |
Буква или числовой символ Unicode, а также знак подчёркивания. |
\s |
Пробельный символ: например, пробел, табуляция или перевод строки. |
\b |
Граница слова: переход между символами \w и \W либо граница строки рядом с \w. |
\. |
Обычная точка без специального значения. |
Если условие ограничивает алфавит латинскими буквами и цифрами, записывайте диапазоны. Класс \w по умолчанию совпадает с кириллицей и поэтому отличается от [A-Za-z0-9_]. Класс \d шире, чем [0-9]. Обозначения \D, \W и \S означают символы, не входящие в соответствующие классы.
Квантификатор задаёт число повторений предыдущего элемента. В шаблоне AB+ повторяется только B. Для повторения блока AB понадобится группа: (?:AB)+.
* — ноль или больше повторов.+ — один или больше повторов.? — ноль или один повтор.{3} — ровно три повтора.{3,} — не меньше трёх повторов.{2,4} — от двух до четырёх повторов включительно.import re
print(re.findall(r"[0-9]{2,4}", "123 12 12345"))
# ['123', '12', '1234']
print(re.findall(r"\b[0-9]{2,4}\b", "123 12 12345"))
# ['123', '12']
Первый шаблон забирает четыре цифры из числа 12345. Второй требует границ слова, поэтому пропускает это число целиком. Учитывайте границы, если условие просит искать отдельные числа, а не фрагменты цифровых цепочек.
Префикс r сохраняет обратные слеши в строковом литерале Python. Запись r"\bPython\b" передаёт модулю re последовательности для обозначения границ слова. Без префикса \b в обычной строке Python означает символ возврата на один знак.
Префикс r не отменяет синтаксис регулярных выражений. Например, модуль re всё равно распознаёт \d как класс цифр. Для поиска буквальной точки нужен шаблон r"\.".
Чтобы подставить переменную в число повторов, совместите префиксы r и f. Фигурные скобки шаблона удваиваются:
import re
n = 3
pattern = rf"[0-9]{{{n}}}"
print(pattern) # [0-9]{3}
print(bool(re.fullmatch(pattern, "123"))) # True
Круглые скобки (...) создают захватывающую группу. Содержимое группы доступно отдельно. Если такая группа одна, findall возвращает её содержимое вместо полного совпадения. При повторении группы сохраняется последнее захваченное значение.
import re
text = "abcabc abcabc"
print(re.findall(r"(abc)+", text))
# ['abc', 'abc']
print(re.findall(r"(?:abc)+", text))
# ['abcabc', 'abcabc']
Конструкция (?:...) объединяет элементы без создания захватывающей группы. Используйте такую запись, когда скобки нужны только для повторения блока. Полное совпадение объекта из finditer доступно через group(0) или group(), первая захватывающая группа — через group(1).
Знак | задаёт альтернативы. Например, cat|dog ищет cat или dog. Варианты проверяются слева направо: A|AB в строке AB сначала найдёт A. Если нужен длинный вариант, учитывайте порядок альтернатив.
Учебное условие: найти максимальную длину непрерывной подстроки, состоящей только из букв A, B и C. В строке XXABCCBAZABC подходят фрагменты ABCCBA и ABC. Их длины равны 6 и 3, поэтому ответ — 6.
import re
text = "XXABCCBAZABC"
answer = max(
(match.end() - match.start()
for match in re.finditer(r"[ABC]+", text)),
default=0
)
print(answer) # 6
Класс [ABC] разрешает три буквы, а знак + объединяет соседние разрешённые символы. Разность end() - start() даёт длину совпадения. Параметр default=0 задаёт ответ для строки без подходящих букв.
Для решения по файлу замените присваивание text на чтение:
with open("24.txt", encoding="utf-8") as file:
text = file.readline().rstrip("\r\n")
Такой код рассчитан на данные в одной строке. Метод rstrip("\r\n") убирает завершающие переводы строк. Пробелы остаются: удалять их без разрешения условия нельзя.
В строке ABABA блок ABA начинается с позиций 0 и 2. Обычный поиск найдёт только первое вхождение: после него продолжит просмотр с позиции 3. Чтобы проверить каждое начало, используйте опережающую проверку (?=...).
import re
text = "ABABA"
matches = [
(match.start(), match.group(1))
for match in re.finditer(r"(?=(ABA))", text)
]
print(matches) # [(0, 'ABA'), (2, 'ABA')]
Опережающая проверка не поглощает символы. Длина полного совпадения равна нулю, а найденный блок хранится в первой группе. Здесь нужен group(1).
Для поиска самой длинной цепочки [ABC]+ опережающая проверка не требуется. Повторная проверка длинного фрагмента с каждой позиции увеличивает время работы. Учитывайте перекрытия, если без них программа пропускает подходящие фрагменты.
Для учебного примера разрешим цифры 0, 6, 7, 8, 9 и бинарные операции вычитания и умножения. Числа неотрицательные, ведущих нулей нет. Начнём с шаблона одного числа: это либо отдельный ноль, либо ненулевая цифра с продолжением.
import re
number = r"(?:0|[6-9][06789]*)"
expression = rf"{number}(?:[-*]{number})*"
for text in ("6*70-8", "06*7", "6**7", "6*0"):
print(text, bool(re.fullmatch(expression, text)))
# 6*70-8 True
# 06*7 False
# 6**7 False
# 6*0 True
После первого числа повторяется блок «операция и число». Поэтому два оператора подряд не подходят. Проверка fullmatch относится ко всей строке. Поиск самого длинного выражения внутри файла — отдельный шаг: учтите допустимые начала и оцените скорость алгоритма.
. означает почти любой символ, а \. — точку..* захватывает максимум, допускаемый оставшейся частью шаблона. Вариант .*? начинает с минимума. Ни один из них сам по себе не решает задачу на максимальную подстроку.A* допускает пустую строку. Если требуется хотя бы одна A, используйте A+.None у search и задавайте начальное значение для поиска максимума.Для тренировки сначала выпишите ожидаемые совпадения вручную. Затем проверьте шаблон на короткой строке, строке без совпадений и строке с повторами. После этого переходите к полному файлу задания ЕГЭ 2027.
Разобраться в Python и отработать задания на строки можно на курсе подготовки к ЕГЭ 2027 по информатике с Колей Касперским в Вебиуме. Видеоуроки помогают изучить тему, домашние задания — закрепить её на практике, а пробники — проверить подготовку в формате экзамена. На курсе предусмотрена поддержка наставника. Записывайтесь, чтобы заниматься по плану и применять изученные алгоритмы в задачах.
Авторизуйтесь, чтобы оставить комментарий.