ээдд. Прохоренок_Н_А__Дронов_В_А_Python_3_и_PyQt_5_Разработка_приложен. Николай Прохоренок Владимир Дронов
Скачать 7.92 Mb.
|
") >>> m.expand(r"<\2><\1>") # \номер ' ' >>> m.expand(r"<\g<2>><\g<1>>") # \g<номер> ' ' >>> m.expand(r"<\g ' ' В качестве примера использования метода search() проверим на соответствие шаблону введенный пользователем адрес электронной почты (листинг 7.6). Листинг 7.6. Проверка e-mail на соответствие шаблону # -*- coding: utf-8 -*- import re email = input("Введите e-mail: ") pe = r"^([a-z0-9_.-]+)@(([a-z0-9-]+\.)+[a-z]{2,6})$" p = re.compile(pe, re.I | re.S) m = p.search(email) if not m: print("E-mail не соответствует шаблону") else: print("E-mail", m.group(0), "соответствует шаблону") print("ящик:", m.group(1), "домен:", m.group(2)) input() Результат выполнения (введенное пользователем значение выделено полужирным шриф- том): Введите e-mail: user@mail.ru E-mail user@mail.ru соответствует шаблону ящик: user домен: mail.ru 136 Часть I. Основы языка Python 7.3. Поиск всех совпадений с шаблоном Для поиска всех совпадений с шаблоном предназначено несколько функций и методов. Метод findall() ищет все совпадения с шаблоном. Формат метода: findall(<Строка>[, <Начальная позиция>[, <Конечная позиция>]]) Если соответствия найдены, возвращается список с фрагментами, в противном случае возвращается пустой список. Если внутри шаблона есть более одной группы, то каждый элемент списка будет кортежем, а не строкой: >>> import re >>> p = re.compile(r"[0-9]+") >>> p.findall("2007, 2008, 2009, 2010, 2011") ['2007', '2008', '2009', '2010', '2011'] >>> p = re.compile(r"[a-z]+") >>> p.findall("2007, 2008, 2009, 2010, 2011") [] >>> t = r"(([0-9]{3})-([0-9]{2})-([0-9]{2}))" >>> p = re.compile(t) >>> p.findall("322-77-20, 528-22-98") [('322-77-20', '322', '77', '20'), ('528-22-98', '528', '22', '98')] Вместо метода findall() можно воспользоваться функцией findall() . Формат функции: re.findall(<Шаблон>, <Строка>[, <Модификатор>]) В параметре <Шаблон> указывается строка с регулярным выражением или скомпилиро- ванное регулярное выражение. В параметре <Модификатор> можно указать флаги, ис- пользуемые в функции compile() : >>> re.findall(r"[0-9]+", "1 2 3 4 5 6") ['1', '2', '3', '4', '5', '6'] >>> p = re.compile(r"[0-9]+") >>> re.findall(p, "1 2 3 4 5 6") ['1', '2', '3', '4', '5', '6'] Метод finditer() аналогичен методу findall() , но возвращает итератор, а не список. На каждой итерации цикла возвращается объект Match . Формат метода: finditer(<Строка>[, <Начальная позиция>[, <Конечная позиция>]]) Пример: >>> p = re.compile(r"[0-9]+") >>> for m in p.finditer("2007, 2008, 2009, 2010, 2011"): print(m.group(0), "start:", m.start(), "end:", m.end()) 2007 start: 0 end: 4 2008 start: 6 end: 10 2009 start: 12 end: 16 2010 start: 18 end: 22 2011 start: 24 end: 28 Глава 7. Регулярные выражения 137 Вместо метода finditer() можно воспользоваться функцией finditer() . Ее формат: re.finditer(<Шаблон>, <Строка>[, <Модификатор>]) В параметре <Шаблон> указывается строка с регулярным выражением или скомпилиро- ванное регулярное выражение. В параметре <Модификатор> можно указать флаги, ис- пользуемые в функции compile() . Получим содержимое между тегами: >>> p = re.compile(r"(.+?)", re.I | re.S) >>> s = "Text1Text2Text3" >>> for m in re.finditer(p, s): print(m.group(1)) Text1 Text3 7.4. Замена в строке Метод sub() ищет все совпадения с шаблоном и заменяет их указанным значением. Если совпадения не найдены, возвращается исходная строка. Метод имеет следующий формат: sub(<Новый фрагмент или ссылка на функцию>, <Строка для замены> [, <Максимальное количество замен>]) Внутри нового фрагмента можно использовать обратные ссылки \номер группы , \g<номер группы> и \g<название группы> . Для примера поменяем два тега местами: >>> import re >>> p = re.compile(r"<(?P >>> p.sub(r"<\2><\1>", " ") # \номер ' ' >>> p.sub(r"<\g<2>><\g<1>>", " ") # \g<номер> ' ' >>> p.sub(r"<\g ") # \g<название> ' ' В качестве первого параметра можно указать ссылку на функцию. В эту функцию будет передаваться объект Match , соответствующий найденному фрагменту. Результат, возвра- щаемый этой функцией, служит фрагментом для замены. Для примера найдем все числа в строке и прибавим к ним число 10 (листинг 7.7). Листинг 7.7. Поиск чисел в строке # -*- coding: utf-8 -*- import re def repl(m): """ Функция для замены. m — объект Match """ x = int(m.group(0)) x += 10 return "{0}".format(x) p = re.compile(r"[0-9]+") # Заменяем все вхождения print(p.sub(repl, "2008, 2009, 2010, 2011")) 138 Часть I. Основы языка Python # Заменяем только первые два вхождения print(p.sub(repl, "2008, 2009, 2010, 2011", 2)) input() Результат выполнения: 2018, 2019, 2020, 2021 2018, 2019, 2010, 2011 В НИМАНИЕ ! Название функции указывается без круглых скобок. Вместо метода sub() можно воспользоваться функцией sub() . Формат функции: re.sub(<Шаблон>, <Новый фрагмент или ссылка на функцию>, <Строка для замены>[, <Максимальное количество замен> [, flags=0]]) В качестве параметра <Шаблон> можно указать строку с регулярным выражением или ском- пилированное регулярное выражение. Для примера поменяем два тега местами, а также изменим регистр букв (листинг 7.8). Листинг 7.8. Перестановка тегов с изменением регистра букв # -*- coding: utf-8 -*- import re def repl(m): """ Функция для замены. m — объект Match """ tag1 = m.group("tag1").upper() tag2 = m.group("tag2").upper() return "<{0}><{1}>".format(tag2, tag1) p = r"<(?P |