Доброго времени суток, читатели, зрители моего канала programmer's notes. Не забывайте подписываться и писать свои комментарии к моим статьям и видео.
Статья является приложением к видео (см. Приложение 1, Приложение 2)
Регулярные выражения в Python
Мы продолжаем интереснейшую тему о регулярных выражениях. Сегодня разберём три темы, связанных с ними.
Использование связки ИЛИ в регулярных выражениях
Очень часто предполагаемый класс строк, который необходимо искать, трудно "втиснуть" в один шаблон. В этом случае помогает связка 'ИЛИ', обозначаемая символом '|'.
В примере ниже, с помощью данной связки объединяются сразу три шаблона.
Результат выполнения
[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.