Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs
На этом занятии
продолжим рассматривать методы модуля re для работы с
регулярными выражениями.
re.match
И следующий метод:
re.match(pattern,
string, flags)
который проверяет
совпадение шаблона pattern в начале строки string с учетом флагов
flags (если они
указаны). Обратите внимание, в отличие от метода search, который ищет
совпадение шаблона в любом месте строки, метод match находит
совпадение только с начала. Он возвращает объект совпадения re.Match, либо значение None, если шаблон не
был найден.
Рассмотрим такой
пример. Пусть в строке ожидается номер телефона в формате:
+7(xxx)xxx-xx-xx
где x – любая цифра.
Нужно его проверить и извлечь из строки. Для этого пропишем следующее правило:
import re
text = "+7(123)456-78-90"
m = re.match(r"\+7\(\d{3}\)\d{3}-\d{2}-\d{2}", text)
print(m)
При запуске
программы получим объект совпадения:
<re.Match
object; span=(0, 16), match='+7(123)456-78-90'>
Но, если вначале
строки добавить любой символ, то совпадение найдено не будет, т.к. метод match() выполняет
анализ только с начала строки.
re.split
Следующий метод:
re.split(pattern,
string, flags)
выполняет
разбивку строки string по заданному шаблону pattern. Например, у
нас имеется вот такой многострочный текст:
text = """<point lon="40.8482" lat="52.6274" />
<point lon="40.8559" lat="52.6361" />; <point lon="40.8614" lat="52.651" />
<point lon="40.8676" lat="52.6585" />, <point lon="40.8672" lat="52.6626" />
"""
Требуется
получить множество строк, которые разделяются между собой или переносом строки
(\n), или символами
«;» и «,». Воспользуемся методом split() со следующим шаблоном:
ar = re.split(r"[\n;,]+", text)
print(ar)
На выходе
получим список из следующих строк:
['<point
lon="40.8482" lat="52.6274" />', '<point
lon="40.8559" lat="52.6361" />', ' <point lon="40.8614"
lat="52.651" />', '<point lon="40.8676"
lat="52.6585" />', ' <point lon="40.8672"
lat="52.6626" />', '']
re.sub и re.subn
Следующий метод:
re.sub(pattern,
repl, string, count, flags)
-
pattern
– регулярное
выражение;
-
repl – строка или
функция для замены найденного выражения;
-
string
– анализируемая
строка;
-
count – максимальное
число замен (если не указано, то неограниченно);
-
flags – набор флагов
(по умолчанию не используются).
Выполняет замену
в строке найденных совпадений строкой или результатом работы функции repl и возвращает
преобразованную строку.
В качестве
примера с помощью метода sub преобразуем вот такой текст:
text = """Москва
Казань
Тверь
Самара
Уфа"""
в список формата
HTML:
<option>Москва</option>
<option>Казань</option>
<option>Тверь</option>
<option>Самара</option>
<option>Уфа</option>
Для этого
запишем вот такой шаблон с последующим параметром для замены найденных
вхождений:
lst = re.sub(r"\s*(\w+)\s*", r"<option>\1</option>\n", text)
print(lst)
Обратите
внимание, в строке замены repl мы можем использовать ссылки на
сохраняющие группы. В данном случае ссылка \1 содержит выделенный город из
текста. Затем эта строка окаймляется тегами <option>\1</option> и
получается искомый список.
Но, кроме строки
можно передавать ссылку на функцию, которая должна возвращать строку,
подставляемую вместо найденного вхождения. Например, добавим тегам option атрибут value:
<option value='1'>Москва</option>
<option value='2'>Казань</option>
<option value='3'>Тверь</option>
<option value='4'>Самара</option>
<option value='5'>Уфа</option>
Для этого
вначале определим функцию:
def counter(start=0):
def repl_find(m):
nonlocal start
start += 1
return f"<option value='{start}'>{m.group(1)}</option>\n"
return repl_find
В качестве
параметра вложенная функция repl_find принимает
ссылку на объект re.Match, в котором хранится информация о
найденном совпадении. И далее формируется строка с атрибутом value, причем,
значение этого атрибута каждый раз увеличивается на 1.
Укажем ссылку на
эту функцию в методе sub:
lst = re.sub(r"\s*(\w+)\s*", counter(), text)
Все, теперь при
каждой замене будет вызываться функция repl_find и возвращать
сформированную строку.
Аналогично
работает и метод:
re.subn(pattern,
repl, string, count, flags)
Только он
возвращает не только преобразованную строку, но и число произведенных замен:
lst, total = re.subn(r"\s*(\w+)\s*", r"<option>\1</option>\n", text)
print(lst, total)
re.compile
Последний метод,
который мы рассмотрим в модуле re – это:
re.compile(pattern, flags)
который
выполняет компиляцию регулярного выражения и возвращает его в виде экземпляра
класса Pattern.
Компиляция
регулярного выражения выполняется, если один и тот же шаблон используется
многократно. Например, нашу предыдущую программу можно записать так:
text = """Москва
Казань
Тверь
Самара
Уфа"""
def counter(start=0):
def repl_find(m):
nonlocal start
start += 1
return f"<option value='{start}'>{m.group(1)}</option>\n"
return repl_find
rx = re.compile(r"\s*(\w+)\s*")
lst, total = rx.subn(r"<option>\1</option>\n", text)
lst2 = rx.sub(counter(), text)
print(lst, total, lst2, sep="\n")
Смотрите, мы
здесь сначала скомпилировали шаблон и сохранили ссылку rx на класс Pattern. Затем, уже из
него вызываем методы subn и sub, но без
указания регулярного выражения, так как эти методы мы вызываем не из модуля re, а из класса Pattern. В нем они
переопределены так, чтобы не писать шаблон, который уже известен.
В общем случае,
класс Pattern имеет все те же
методы, что и модуль re и дополнительно несколько уникальных
свойств:
-
flags – возвращает
список флагов, которые были установлены при компиляции;
-
pattern
– строка
исходного шаблона;
-
groupindex – словарь, ключами
которого являются имена сохраняющих групп, а значениями – номера групп (пустой,
если имена не используются).
Вот так можно
оперировать регулярными выражениями, используя методы модуля re.
Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs