Найти тему
programmer's notes (python and more)

Программирование на Python. Регулярные выражения в Python. Жадность регулярных выражений и связка ИЛИ. Приложение 3

Доброго времени суток, читатели, зрители моего канала programmer's notes. Не забывайте подписываться и писать свои комментарии к моим статьям и видео.

Алгоритмы на Python | programmer's notes (python and more) | Дзен
Стандартные библиотеки Python | programmer's notes (python and more) | Дзен
Регулярные выражения в Python | programmer's notes (python and more) | Дзен

Статья является приложением к видео (см. Приложение 1, Приложение 2)

Регулярные выражения в Python

Мы продолжаем интереснейшую тему о регулярных выражениях. Сегодня разберём три темы, связанных с ними.

Использование связки ИЛИ в регулярных выражениях

Очень часто предполагаемый класс строк, который необходимо искать, трудно "втиснуть" в один шаблон. В этом случае помогает связка 'ИЛИ', обозначаемая символом '|'.

В примере ниже, с помощью данной связки объединяются сразу три шаблона.

Текст программы см. ниже
Текст программы см. ниже
primer128.py

Результат выполнения

[13, 14] 1
[50, 52] ab
[103, 104] Й

Следующий пример показывает выделение в строке выражения типа x = число, но только для определённых ключей lo и ot. Шаблоны учитывают возможное наличие пробелов между ключом и знаком равенства, между знаком равенства и числом, между числом и точкой с запятой. Вариант fdsdlo=33; не должен выделяться, так как не соответствует правильному ключу, для используется спецсимвол \b - начало слова.

#!/usr/bin/python3
import re
s = 'lo = 3456;qwerty lo = 3 ; fdsdlo=33;\
ot=456;'
pt = r'\blo[ ]*=[ ]*[0-9]+[ ]*;|\bot[ ]*=[ ]*[0-9]+[ ]*;'
m = re.findall(pt, s)
print(m)

Результат выполнения

['lo = 3456;', 'lo = 3 ;', 'ot=456;']

Замечание
Вообще выражение ключ=значение, встречается довольно часто. Это и ini-файлы и разные журналы, содержащие информацию о процессах также могут иметь подобную структуру. Так что полученный результат довольно полезен. Напоминаю, что \b указывает на начало слова.

Жадные и ленивые регулярные выражения

Да, среди регулярных выражений встречаются и жадные и ленивые. Начнём со следующего примера.

#!/usr/bin/python3
import re
pt = r'[b]{2,3}'
s = 'abc bbb bb asbbb1'
f = re.findall(pt, s)
print(f)

Результат выполнения

['bbb', 'bb', 'bbb']

Обратите внимание, что найдены самые длинные последовательности, по верхней границе 3. Забавный вариант, не так ли. Вот это и есть беспросветная жадность регулярных выражений.

Оказывается эту самую жадность можно легко укротить. Для этого используется знак '?'.

#!/usr/bin/python3
import re
pt = r'[b]{2,3}?'
s = 'abc bbb bb asbbb1'
f = re.findall(pt, s)
print(f)

А вот теперь результат выполнения

['bb', 'bb', 'bb']

За основу взят поиск по нижней границу. Bот это и называется ленивым подходом. Замечу, что в нашем примере, жадный вариант больше подходит для выполнения анализа. Но это бывает далеко не всегда.

Рассмотрим еще один пример.

#!/usr/bin/python3
import re
s = 'После своего объяснения с женой Пьер поехал в Петербург. \
В Торжке на станции не было лошадей, или не хотел их дать \
смотритель. Пьер должен был ждать.'
pt = r'.*\.'
f = re.findall(pt, s)
print(f)

Результат выполнения

['После своего объяснения с женой Пьер поехал в Петербург. В Торжке на станции не было лошадей, или не хотел их дать смотритель. Пьер должен был ждать.']

А вот это уже интересно. Был захвачен весь текст. А почему? Да потому что требуется захватить последовательность с точкой на конце. И жадный подход предпочитает взять всю строку, ведь она также заканчивается точкой, т.е. взять самую длинную последовательность. Конечно этому способствует вот это выражение '.*', т.е. любая последовательность.

Теперь изменим регулярное выражение используя знак вопроса.

#!/usr/bin/python3
import re
s = 'После своего объяснения с женой Пьер поехал в Петербург. \
В Торжке на станции не было лошадей, или не хотел их дать \
смотритель. Пьер должен был ждать.'
pt = r'.*?\.'
f = re.findall(pt, s)
print(f)

Результат выполнения

['После своего объяснения с женой Пьер поехал в Петербург.', ' В Торжке на станции не было лошадей, или не хотел их дать смотритель.', ' Пьер должен был ждать.']

А вот это то, что нужно. Мы получили все предложения.

Хорошего программирования. Оставляйте свои комментарии, не забывайте про лайки и подписывайтесь на мой канал programmer's notes.

Лень и жадность это грех. Нужно ли заменять один грех на другой?
Лень и жадность это грех. Нужно ли заменять один грех на другой?