Регулярное выражение для номера телефона python

Регулярные выражения в Python от простого к сложному

Решил я давеча моим школьникам дать задачек на регулярные выражения для изучения. А к задачкам нужна какая-нибудь теория. И стал я искать хорошие тексты на русском. Пяток сносных нашёл, но всё не то. Что-то смято, что-то упущено. У этих текстов был не только фатальный недостаток. Мало картинок, мало примеров. И почти нет разумных задач. Ну неужели поиск IP-адреса — это самая частая задача для регулярных выражений? Вот и я думаю, что нет.
Про разницу (?:…) / (…) фиг найдёшь, а без этого знания в некоторых случаях можно только страдать.

Плюс в питоне есть немало регулярных плюшек. Например, re.split может добавлять тот кусок текста, по которому был разрез, в список частей. А в re.sub можно вместо шаблона для замены передать функцию. Это — реальные вещи, которые прямо очень нужны, но никто про это не пишет.
Так и родился этот достаточно многобуквенный материал с подробностями, тонкостями, картинками и задачами.

Надеюсь, вам удастся из него извлечь что-нибудь новое и полезное, даже если вы уже в ладах с регулярками.
PS. Решения задач школьники сдают в тестирующую систему, поэтому задачи оформлены в несколько формальном виде.

Содержание

Регулярные выражения в Python от простого к сложному;
Содержание;
    Примеры регулярных выражений;
    Сила и ответственность;
Документация и ссылки;
Основы синтаксиса;
    Шаблоны, соответствующие одному символу;
    Квантификаторы (указание количества повторений);
    Жадность в регулярках и границы найденного шаблона;
    Пересечение подстрок;
Эксперименты в песочнице;
Регулярки в питоне;
Пример использования всех основных функций;
    Тонкости экранирования в питоне (‘\\\\foo’);
    Использование дополнительных флагов в питоне;
Написание и тестирование регулярных выражений;
Задачи — 1;
Скобочные группы (?:…) и перечисления |;
    Перечисления (операция «ИЛИ»);
    Скобочные группы (группировка плюс квантификаторы);
    Скобки плюс перечисления;
    Ещё примеры;
Задачи — 2;
Группирующие скобки (…) и match-объекты в питоне;
    Match-объекты;
    Группирующие скобки (…);
    Тонкости со скобками и нумерацией групп.;
    Группы и re.findall;
    Группы и re.split;
Использование групп при заменах;
    Замена с обработкой шаблона функцией в питоне;
    Ссылки на группы при поиске;
Задачи — 3;
Шаблоны, соответствующие не конкретному тексту, а позиции;
    Простые шаблоны, соответствующие позиции;
    Сложные шаблоны, соответствующие позиции (lookaround и Co);
    lookaround на примере королей и императоров Франции;
Задачи — 4;
Post scriptum;

Регулярное выражение — это строка, задающая шаблон поиска подстрок в тексте. Одному шаблону может соответствовать много разных строчек. Термин «Регулярные выражения» является переводом английского словосочетания «Regular expressions». Перевод не очень точно отражает смысл, правильнее было бы «шаблонные выражения». Регулярное выражение, или коротко «регулярка», состоит из обычных символов и специальных командных последовательностей. Например, d задаёт любую цифру, а d+ — задает любую последовательность из одной или более цифр. Работа с регулярками реализована во всех современных языках программирования. Однако существует несколько «диалектов», поэтому функционал регулярных выражений может различаться от языка к языку. В некоторых языках программирования регулярками пользоваться очень удобно (например, в питоне), в некоторых — не слишком (например, в C++).

Примеры регулярных выражений

Сила и ответственность

Регулярные выражения, или коротко, регулярки — это очень мощный инструмент. Но использовать их следует с умом и осторожностью, и только там, где они действительно приносят пользу, а не вред. Во-первых, плохо написанные регулярные выражения работают медленно. Во-вторых, их зачастую очень сложно читать, особенно если регулярка написана не лично тобой пять минут назад. В-третьих, очень часто даже небольшое изменение задачи (того, что требуется найти) приводит к значительному изменению выражения. Поэтому про регулярки часто говорят, что это write only code (код, который только пишут с нуля, но не читают и не правят). А также шутят: Некоторые люди, когда сталкиваются с проблемой, думают «Я знаю, я решу её с помощью регулярных выражений.» Теперь у них две проблемы. Вот пример write-only регулярки (для проверки валидности e-mail адреса (не надо так делать!!!)):

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[x01-x08x0bx0cx0e-x1fx21x23-x5bx5d-x7f]|\[x01-x09x0bx0cx0e-x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|[(?:(?:25[0-5]|
2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[x01-x08x0bx0cx0e-x1fx21-x5ax53-x7f]|\[x01-x09x0bx0cx0e-x7f])+)])

А вот здесь более точная регулярка для проверки корректности email адреса стандарту RFC822. Если вдруг будете проверять email, то не делайте так!Если адрес вводит пользователь, то пусть вводит почти что угодно, лишь бы там была собака. Надёжнее всего отправить туда письмо и убедиться, что пользователь может его получить.

Документация и ссылки

  • Оригинальная документация: https://docs.python.org/3/library/re.html;
  • Очень подробный и обстоятельный материал: https://www.regular-expressions.info/;
  • Разные сложные трюки и тонкости с примерами: http://www.rexegg.com/;
  • Он-лайн отладка регулярок https://regex101.com (не забудьте поставить галочку Python в разделе FLAVOR слева);
  • Он-лайн визуализация регулярок https://www.debuggex.com/ (не забудьте выбрать Python);
  • Могущественный текстовый редактор Sublime text 3, в котором очень удобный поиск по регуляркам;

Основы синтаксиса

Любая строка (в которой нет символов .^$*+?{}[]|()) сама по себе является регулярным выражением. Так, выражению Хаха будет соответствовать строка “Хаха” и только она. Регулярные выражения являются регистрозависимыми, поэтому строка “хаха” (с маленькой буквы) уже не будет соответствовать выражению выше. Подобно строкам в языке Python, регулярные выражения имеют спецсимволы .^$*+?{}[]|(), которые в регулярках являются управляющими конструкциями. Для написания их просто как символов требуется их экранировать, для чего нужно поставить перед ними знак . Так же, как и в питоне, в регулярных выражениях выражение n соответствует концу строки, а t — табуляции.

Шаблоны, соответствующие одному символу

Во всех примерах ниже соответствия регулярному выражению выделяются бирюзовым цветом с подчёркиванием.

Квантификаторы (указание количества повторений)

Жадность в регулярках и границы найденного шаблона

Как указано выше, по умолчанию квантификаторы жадные. Этот подход решает очень важную проблему — проблему границы шаблона. Скажем, шаблон d+ захватывает максимально возможное количество цифр. Поэтому можно быть уверенным, что перед найденным шаблоном идёт не цифра, и после идёт не цифра. Однако если в шаблоне есть не жадные части (например, явный текст), то подстрока может быть найдена неудачно. Например, если мы хотим найти «слова», начинающиеся на СУ, после которой идут цифры, при помощи регулярки СУd*, то мы найдём и неправильные шаблоны:

ПАСУ13 СУ12, ЧТОБЫ СУ6ЕНИЕ УДАЛОСЬ.

В тех случаях, когда это важно, условие на границу шаблона нужно обязательно добавлять в регулярку. О том, как это можно делать, будет дальше.

Пересечение подстрок

В обычной ситуации регулярки позволяют найти только непересекающиеся шаблоны. Вместе с проблемой границы слова это делает их использование в некоторых случаях более сложным. Например, если мы решим искать e-mail адреса при помощи неправильной регулярки w+@w+ (или даже лучше, [w'._+-]+@[w'._+-]+), то в неудачном случае найдём вот что:

foo@boo@goo@moo@roo@zoo

То есть это с одной стороны и не e-mail, а с другой стороны это не все подстроки вида текст-собака-текст, так как boo@goo и moo@roo пропущены.

Эксперименты в песочнице

Если вы впервые сталкиваетесь с регулярными выражениями, то лучше всего сначала попробовать песочницу. Посмотрите, как работают простые шаблоны и квантификаторы. Решите следующие задачи для этого текста (возможно, к части придётся вернуться после следующей теории):

  1. Найдите все натуральные числа (возможно, окружённые буквами);
  2. Найдите все «слова», написанные капсом (то есть строго заглавными), возможно внутри настоящих слов (аааБББввв);
  3. Найдите слова, в которых есть русская буква, а когда-нибудь за ней цифра;
  4. Найдите все слова, начинающиеся с русской или латинской большой буквы (b — граница слова);
  5. Найдите слова, которые начинаются на гласную (b — граница слова);;
  6. Найдите все натуральные числа, не находящиеся внутри или на границе слова;
  7. Найдите строчки, в которых есть символ * (. — это точно не конец строки!);
  8. Найдите строчки, в которых есть открывающая и когда-нибудь потом закрывающая скобки;
  9. Выделите одним махом весь кусок оглавления (в конце примера, вместе с тегами);
  10. Выделите одним махом только текстовую часть оглавления, без тегов;
  11. Найдите пустые строчки;

Регулярки в питоне

Функции для работы с регулярками живут в модуле re. Основные функции:

Пример использования всех основных функций

import re 

match = re.search(r'ddDdd', r'Телефон 123-12-12') 
print(match[0] if match else 'Not found') 
# -> 23-12 
match = re.search(r'ddDdd', r'Телефон 1231212') 
print(match[0] if match else 'Not found') 
# -> Not found 

match = re.fullmatch(r'ddDdd', r'12-12') 
print('YES' if match else 'NO') 
# -> YES 
match = re.fullmatch(r'ddDdd', r'Т. 12-12') 
print('YES' if match else 'NO') 
# -> NO 

print(re.split(r'W+', 'Где, скажите мне, мои очки??!')) 
# -> ['Где', 'скажите', 'мне', 'мои', 'очки', ''] 

print(re.findall(r'dd.dd.d{4}', 
                 r'Эта строка написана 19.01.2018, а могла бы и 01.09.2017')) 
# -> ['19.01.2018', '01.09.2017'] 

for m in re.finditer(r'dd.dd.d{4}', r'Эта строка написана 19.01.2018, а могла бы и 01.09.2017'): 
    print('Дата', m[0], 'начинается с позиции', m.start()) 
# -> Дата 19.01.2018 начинается с позиции 20 
# -> Дата 01.09.2017 начинается с позиции 45 

print(re.sub(r'dd.dd.d{4}', 
             r'DD.MM.YYYY', 
             r'Эта строка написана 19.01.2018, а могла бы и 01.09.2017')) 
# -> Эта строка написана DD.MM.YYYY, а могла бы и DD.MM.YYYY 

Тонкости экранирования в питоне ('\\\\foo')

Так как символ в питоновских строках также необходимо экранировать, то в результате в шаблонах могут возникать конструкции вида '\\par'. Первый слеш означает, что следующий за ним символ нужно оставить «как есть». Третий также. В результате с точки зрения питона '\\' означает просто два слеша \. Теперь с точки зрения движка регулярных выражений, первый слеш экранирует второй. Тем самым как шаблон для регулярки '\\par' означает просто текст par. Для того, чтобы не было таких нагромождений слешей, перед открывающей кавычкой нужно поставить символ r, что скажет питону «не рассматривай как экранирующий символ (кроме случаев экранирования открывающей кавычки)». Соответственно можно будет писать r'\par'.

Использование дополнительных флагов в питоне

Каждой из функций, перечисленных выше, можно дать дополнительный параметр flags, что несколько изменит режим работы регулярок. В качестве значения нужно передать сумму выбранных констант, вот они:

import re 
print(re.findall(r'd+', '12 + ٦٧')) 
# -> ['12', '٦٧'] 
print(re.findall(r'w+', 'Hello, мир!')) 
# -> ['Hello', 'мир'] 
print(re.findall(r'd+', '12 + ٦٧', flags=re.ASCII)) 
# -> ['12'] 
print(re.findall(r'w+', 'Hello, мир!', flags=re.ASCII)) 
# -> ['Hello'] 
print(re.findall(r'[уеыаоэяию]+', 'ОООО ааааа ррррр ЫЫЫЫ яяяя')) 
# -> ['ааааа', 'яяяя'] 
print(re.findall(r'[уеыаоэяию]+', 'ОООО ааааа ррррр ЫЫЫЫ яяяя', flags=re.IGNORECASE)) 
# -> ['ОООО', 'ааааа', 'ЫЫЫЫ', 'яяяя'] 

text = r""" 
Торт 
с вишней1 
вишней2 
""" 
print(re.findall(r'Торт.с', text)) 
# -> [] 
print(re.findall(r'Торт.с', text, flags=re.DOTALL)) 
# -> ['Тортnс'] 
print(re.findall(r'вишw+', text, flags=re.MULTILINE)) 
# -> ['вишней1', 'вишней2'] 
print(re.findall(r'^вишw+', text, flags=re.MULTILINE)) 
# -> ['вишней2'] 

Написание и тестирование регулярных выражений

Для написания и тестирования регулярных выражений удобно использовать сервис https://regex101.com (не забудьте поставить галочку Python в разделе FLAVOR слева) или текстовый редактор Sublime text 3.

Задачи — 1

Задача 01. Регистрационные знаки транспортных средств

В России применяются регистрационные знаки нескольких видов.
Общего в них то, что они состоят из цифр и букв. Причём используются только 12 букв кириллицы, имеющие графические аналоги в латинском алфавите — А, В, Е, К, М, Н, О, Р, С, Т, У и Х.

У частных легковых автомобилях номера — это буква, три цифры, две буквы, затем две или три цифры с кодом региона. У такси — две буквы, три цифры, затем две или три цифры с кодом региона. Есть также и другие виды, но в этой задаче они не понадобятся.

Вам потребуется определить, является ли последовательность букв корректным номером указанных двух типов, и если является, то каким.

На вход даются строки, которые претендуют на то, чтобы быть номером. Определите тип номера. Буквы в номерах — заглавные русские. Маленькие и английские для простоты можно игнорировать.

Задача 02. Количество слов

Слово — это последовательность из букв (русских или английских), внутри которой могут быть дефисы.
На вход даётся текст, посчитайте, сколько в нём слов.
PS. Задача решается в одну строчку. Никакие хитрые техники, не упомянутые выше, не требуются.

Задача 03. Поиск e-mailов

Допустимый формат e-mail адреса регулируется стандартом RFC 5322.
Если говорить вкратце, то e-mail состоит из одного символа @ (at-символ или собака), текста до собаки (Local-part) и текста после собаки (Domain part). Вообще в адресе может быть всякий беспредел (вкратце можно прочитать о нём в википедии). Довольно странные штуки могут быть валидным адресом, например:
"very.(),:;<>[]".VERY."very@\ "very".unusual"@[IPv6:2001:db8::1]
"()<>[]:,;@\"!#$%&'-/=?^_`{}| ~.a"@(comment)exa-mple
Но большинство почтовых сервисов такой ад и вакханалию не допускают. И мы тоже не будем :)

Будем рассматривать только адреса, имя которых состоит из не более, чем 64 латинских букв, цифр и символов '._+-, а домен — из не более, чем 255 латинских букв, цифр и символов .-. Ни Local-part, ни Domain part не может начинаться или заканчиваться на .+-, а ещё в адресе не может быть более одной точки подряд.
Кстати, полезно знать, что часть имени после символа + игнорируется, поэтому можно использовать синонимы своего адреса (например, shаshkоv+spam@179.ru и shаshkоv+vk@179.ru), для того, чтобы упростить себе сортировку почты. (Правда не все сайты позволяют использовать «+», увы)

На вход даётся текст. Необходимо вывести все e-mail адреса, которые в нём встречаются. В общем виде задача достаточно сложная, поэтому у нас будет 3 ограничения:
две точки внутри адреса не встречаются;
две собаки внутри адреса не встречаются;
считаем, что e-mail может быть частью «слова», то есть в boo@ya_ru мы видим адрес boo@ya, а в foo№boo@ya.ru видим boo@ya.ru.

PS. Совсем не обязательно делать все проверки только регулярками. Регулярные выражения — это просто инструмент, который делает часть задач простыми. Не нужно делать их назад сложными :)

Скобочные группы (?:...) и перечисления |

Перечисления (операция «ИЛИ»)

Чтобы проверить, удовлетворяет ли строка хотя бы одному из шаблонов, можно воспользоваться аналогом оператора or, который записывается с помощью символа |. Так, некоторая строка подходит к регулярному выражению A|B тогда и только тогда, когда она подходит хотя бы к одному из регулярных выражений A или B. Например, отдельные овощи в тексте можно искать при помощи шаблона морковк|св[её]кл|картошк|редиск.

Скобочные группы (группировка плюс квантификаторы)

Зачастую шаблон состоит из нескольких повторяющихся групп. Так, MAC-адрес сетевого устройства обычно записывается как шесть групп из двух шестнадцатиричных цифр, разделённых символами - или :. Например, 01:23:45:67:89:ab. Каждый отдельный символ можно задать как [0-9a-fA-F], и можно весь шаблон записать так:
[0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}

Ситуация становится гораздо сложнее, когда количество групп заранее не зафиксировано.
Чтобы разрешить эту проблему в синтаксисе регулярных выражений есть группировка (?:...). Можно писать круглые скобки и без значков ?:, однако от этого у группировки значительно меняется смысл, регулярка начинает работать гораздо медленнее. Об этом будет написано ниже. Итак, если REGEXP — шаблон, то (?:REGEXP) — эквивалентный ему шаблон. Разница только в том, что теперь к (?:REGEXP) можно применять квантификаторы, указывая, сколько именно раз должна повториться группа. Например, шаблон для поиска MAC-адреса, можно записать так:
[0-9a-fA-F]{2}(?:[:-][0-9a-fA-F]{2}){5}

Скобки плюс перечисления

Также скобки (?:...) позволяют локализовать часть шаблона, внутри которого происходит перечисление. Например, шаблон (?:он|тот) (?:шёл|плыл) соответствует каждой из строк «он шёл», «он плыл», «тот шёл», «тот плыл», и является синонимом он шёл|он плыл|тот шёл|тот плыл.

Ещё примеры

Задачи — 2

Задача 04. Замена времени

Вовочка подготовил одно очень важное письмо, но везде указал неправильное время.
Поэтому нужно заменить все вхождения времени на строку (TBD). Время — это строка вида HH:MM:SS или HH:MM, в которой HH — число от 00 до 23, а MM и SS — число от 00 до 59.

Задача 05. Действительные числа в паскале

Pascal requires that real constants have either a decimal point, or an exponent (starting with the letter e or E, and officially called a scale factor), or both, in addition to the usual collection of decimal digits. If a decimal point is included it must have at least one decimal digit on each side of it. As expected, a sign (+ or -) may precede the entire number, or the exponent, or both. Exponents may not include fractional digits. Blanks may precede or follow the real constant, but they may not be embedded within it. Note that the Pascal syntax rules for real constants make no assumptions about the range of real values, and neither does this problem. Your task in this problem is to identify legal Pascal real constants.

Задача 06. Аббревиатуры

Владимир устроился на работу в одно очень важное место. И в первом же документе он ничего не понял,
там были сплошные ФГУП НИЦ ГИДГЕО, ФГОУ ЧШУ АПК и т.п. Тогда он решил собрать все аббревиатуры, чтобы потом найти их расшифровки на http://sokr.ru/. Помогите ему.

Будем считать аббревиатурой слова только лишь из заглавных букв (как минимум из двух). Если несколько таких слов разделены пробелами, то они
считаются одной аббревиатурой.

Группирующие скобки (...) и match-объекты в питоне

Match-объекты

Если функции re.search, re.fullmatch не находят соответствие шаблону в строке, то они возвращают None, функция re.finditer не выдаёт ничего. Однако если соответствие найдено, то возвращается match-объект. Эта штука содержит в себе кучу полезной информации о соответствии шаблону. Полный набор атрибутов можно посмотреть в документации, а здесь приведём самое полезное.

Группирующие скобки (...)

Если в шаблоне регулярного выражения встречаются скобки (...) без ?:, то они становятся группирующими. В match-объекте, который возвращают re.search, re.fullmatch и re.finditer, по каждой такой группе можно получить ту же информацию, что и по всему шаблону. А именно часть подстроки, которая соответствует (...), а также индексы начала и окончания в исходной строке. Достаточно часто это бывает полезно.

import re 
pattern = r's*([А-Яа-яЁё]+)(d+)s*' 
string = r'---   Опять45   ---' 
match = re.search(pattern, string) 
print(f'Найдена подстрока >{match[0]}< с позиции {match.start(0)} до {match.end(0)}') 
print(f'Группа букв >{match[1]}< с позиции {match.start(1)} до {match.end(1)}') 
print(f'Группа цифр >{match[2]}< с позиции {match.start(2)} до {match.end(2)}') 
### 
# -> Найдена подстрока >   Опять45   < с позиции 3 до 16 
# -> Группа букв >Опять< с позиции 6 до 11 
# -> Группа цифр >45< с позиции 11 до 13 


Тонкости со скобками и нумерацией групп.

Если к группирующим скобкам применён квантификатор (то есть указано число повторений), то подгруппа в match-объекте будет создана только для последнего соответствия. Например, если бы в примере выше квантификаторы были снаружи от скобок 's*([А-Яа-яЁё])+(d)+s*', то вывод был бы таким:

# -> Найдена подстрока >   Опять45   < с позиции 3 до 16 
# -> Группа букв >ь< с позиции 10 до 11 
# -> Группа цифр >5< с позиции 12 до 13 

Внутри группирующих скобок могут быть и другие группирующие скобки. В этом случае их нумерация производится в соответствии с номером появления открывающей скобки с шаблоне.

import re 
pattern = r'((d)(d))((d)(d))' 
string = r'123456789' 
match = re.search(pattern, string) 
print(f'Найдена подстрока >{match[0]}< с позиции {match.start(0)} до {match.end(0)}') 
for i in range(1, 7): 
    print(f'Группа №{i} >{match[i]}< с позиции {match.start(i)} до {match.end(i)}') 
### 
# -> Найдена подстрока >1234< с позиции 0 до 4 
# -> Группа №1 >12< с позиции 0 до 2 
# -> Группа №2 >1< с позиции 0 до 1 
# -> Группа №3 >2< с позиции 1 до 2 
# -> Группа №4 >34< с позиции 2 до 4 
# -> Группа №5 >3< с позиции 2 до 3 
# -> Группа №6 >4< с позиции 3 до 4 

Группы и re.findall

Если в шаблоне есть группирующие скобки, то вместо списка найденных подстрок будет возвращён список кортежей, в каждом из которых только соответствие каждой группе. Это не всегда происходит по плану, поэтому обычно нужно использовать негруппирующие скобки (?:...).

import re 
print(re.findall(r'([a-z]+)(d*)', r'foo3, im12, go, 24buz42')) 
# -> [('foo', '3'), ('im', '12'), ('go', ''), ('buz', '42')] 

Группы и re.split

Если в шаблоне нет группирующих скобок, то re.split работает очень похожим образом на str.split. А вот если группирующие скобки в шаблоне есть, то между каждыми разрезанными строками будут все соответствия каждой из подгрупп.

import re 
print(re.split(r'(s*)([+*/-])(s*)', r'12  +  13*15   - 6')) 
# -> ['12', '  ', '+', '  ', '13', '', '*', '', '15', '   ', '-', ' ', '6'] 

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

import re 
print(re.split(r's*([+*/-])s*', r'12  +  13*15   - 6')) 
# -> ['12', '+', '13', '*', '15', '-', '6'] 

Использование групп при заменах

Использование групп добавляет замене (re.sub, работает не только в питоне, а почти везде) очень удобную возможность: в шаблоне для замены можно ссылаться на соответствующую группу при помощи 1, 2, 3, .... Например, если нужно даты из неудобного формата ММ/ДД/ГГГГ перевести в удобный ДД.ММ.ГГГГ, то можно использовать такую регулярку:

import re 
text = "We arrive on 03/25/2018. So you are welcome after 04/01/2018." 
print(re.sub(r'(dd)/(dd)/(d{4})', r'2.1.3', text)) 
# -> We arrive on 25.03.2018. So you are welcome after 01.04.2018. 

Если групп больше 9, то можно ссылаться на них при помощи конструкции вида g<12>.

Замена с обработкой шаблона функцией в питоне

Ещё одна питоновская фича для регулярных выражений: в функции re.sub вместо текста для замены можно передать функцию, которая будет получать на вход match-объект и должна возвращать строку, на которую и будет произведена замена. Это позволяет не писать ад в шаблоне для замены, а использовать удобную функцию. Например, «зацензурим» все слова, начинающиеся на букву «Х»:

import re 
def repl(m): 
    return '>censored(' + str(len(m[0])) + ')<' 
text = "Некоторые хорошие слова подозрительны: хор, хоровод, хороводоводовед." 
print(re.sub(r'b[хХxX]w*', repl, text)) 
# -> Некоторые >censored(7)< слова подозрительны: >censored(3)<, >censored(7)<, >censored(15)<. 

Ссылки на группы при поиске

При помощи 1, 2, 3, ... и g<12> можно ссылаться на найденную группу и при поиске. Необходимость в этом встречается довольно редко, но это бывает полезно при обработке простых xml и html.

Только пообещайте, что не будете парсить сложный xml и тем более html при помощи регулярок! Регулярные выражения для этого не подходят. Используйте другие инструменты. Каждый раз, когда неопытный программист парсит html регулярками, в мире умирает котёнок. Если кажется «Да здесь очень простой html, напишу регулярку», то сразу вспоминайте шутку про две проблемы. Не нужно пытаться парсить html регулярками, даже Пётр Митричев не сможет это сделать в общем случае :) Использование регулярных выражений при парсинге html подобно залатыванию резиновой лодки шилом. Закон Мёрфи для парсинга html и xml при помощи регулярок гласит: парсинг html и xml регулярками иногда работает, но в точности до того момента, когда правильность результата будет очень важна.

Используйте lxml и beautiful soup.

import re 
text = "SPAM <foo>Here we can <boo>find</boo> something interesting</foo> SPAM" 
print(re.search(r'<(w+?)>.*?</1>', text)[0]) 
# -> <foo>Here we can <boo>find</boo> something interesting</foo> 
text = "SPAM <foo>Here we can <foo>find</foo> OH, NO MATCH HERE!</foo> SPAM" 
print(re.search(r'<(w+?)>.*?</1>', text)[0]) 
# -> <foo>Here we can <foo>find</foo> 

Задачи — 3

Задача 07. Шифровка

Владимиру потребовалось срочно запутать финансовую документацию. Но так, чтобы это было обратимо.
Он не придумал ничего лучше, чем заменить каждое целое число (последовательность цифр) на его куб. Помогите ему.

Задача 08. То ли акростих, то ли акроним, то ли апроним

Акростих — осмысленный текст, сложенный из начальных букв каждой строки стихотворения.
Акроним — вид аббревиатуры, образованной начальными звуками (напр. НАТО, вуз, НАСА, ТАСС), которое можно произнести слитно (в отличие от аббревиатуры, которую произносят «по буквам», например: КГБ — «ка-гэ-бэ»).
На вход даётся текст. Выведите слитно первые буквы каждого слова. Буквы необходимо выводить заглавными.
Эту задачу можно решить в одну строчку.

Задача 09. Хайку

Хайку — жанр традиционной японской лирической поэзии века, известный с XIV века.
Оригинальное японское хайку состоит из 17 слогов, составляющих один столбец иероглифов. Особыми разделительными словами — кирэдзи — текст хайку делится на части из 5, 7 и снова 5 слогов. При переводе хайку на западные языки традиционно вместо разделительного слова использую разрыв строки и, таким образом, хайку записываются как трёхстишия.

Перед вами трёхстишия, которые претендуют на то, чтобы быть хайку. В качестве разделителя строк используются символы / . Если разделители делят текст на строки, в которых 5/7/5 слогов, то выведите «Хайку!». Если число строк не равно 3, то выведите строку «Не хайку. Должно быть 3 строки.» Иначе выведите строку вида «Не хайку. В i строке слогов не s, а j.», где строка i — самая ранняя, в которой количество слогов неправильное.

Для простоты будем считать, что слогов ровно столько же, сколько гласных, не задумываясь о тонкостях.

Шаблоны, соответствующие не конкретному тексту, а позиции

Отдельные части регулярного выражения могут соответствовать не части текста, а позиции в этом тексте. То есть такому шаблону соответствует не подстрока, а некоторая позиция в тексте, как бы «между» буквами.

Простые шаблоны, соответствующие позиции

Для определённости строку, в которой мы ищем шаблон будем называть всем текстом.Каждую строчку всего текста (то есть каждый максимальный кусок без символов конца строки) будем называть строчкой текста.

Сложные шаблоны, соответствующие позиции (lookaround и Co)

Следующие шаблоны применяются в основном в тех случаях, когда нужно уточнить, что должно идти непосредственно перед или после шаблона, но при этом
не включать найденное в match-объект.

На всякий случай ещё раз. Каждый их этих шаблонов проверяет лишь то, что идёт непосредственно перед позицией или непосредственно после позиции. Если пару таких шаблонов написать рядом, то проверки будут независимы (то есть будут соответствовать AND в каком-то смысле).

lookaround на примере королей и императоров Франции

Людовик(?=VI) — Людовик, за которым идёт VI

КарлIV, КарлIX, КарлV, КарлVI, КарлVII, КарлVIII,
ЛюдовикIX, ЛюдовикVI, ЛюдовикVII, ЛюдовикVIII, ЛюдовикX, …, ЛюдовикXVIII,
ФилиппI, ФилиппII, ФилиппIII, ФилиппIV, ФилиппV, ФилиппVI

Людовик(?!VI) — Людовик, за которым идёт не VI

КарлIV, КарлIX, КарлV, КарлVI, КарлVII, КарлVIII,
ЛюдовикIX, ЛюдовикVI, ЛюдовикVII, ЛюдовикVIII, ЛюдовикX, …, ЛюдовикXVIII,
ФилиппI, ФилиппII, ФилиппIII, ФилиппIV, ФилиппV, ФилиппVI

(?<=Людовик)VI — «шестой», но только если Людовик

КарлIV, КарлIX, КарлV, КарлVI, КарлVII, КарлVIII,
ЛюдовикIX, ЛюдовикVI, ЛюдовикVII, ЛюдовикVIII, ЛюдовикX, …, ЛюдовикXVIII,
ФилиппI, ФилиппII, ФилиппIII, ФилиппIV, ФилиппV, ФилиппVI

(?<!Людовик)VI — «шестой», но только если не Людовик

КарлIV, КарлIX, КарлV, КарлVI, КарлVII, КарлVIII,
ЛюдовикIX, ЛюдовикVI, ЛюдовикVII, ЛюдовикVIII, ЛюдовикX, …, ЛюдовикXVIII,
ФилиппI, ФилиппII, ФилиппIII, ФилиппIV, ФилиппV, ФилиппVI


Прочие фичи

Конечно, здесь описано не всё, что умеют регулярные выражения, и даже не всё, что умеют регулярные выражения в питоне. За дальнейшим можно обращаться к этому разделу. Из полезного за кадром осталась компиляция регулярок для ускорения многократного использования одного шаблона, использование именных групп и разные хитрые трюки.
А уж какие извращения можно делать с регулярными выражениями в языке Perl — поручик Ржевский просто отдыхает :)

Задачи — 4

Задача 10. CamelCase -> under_score

Владимир написал свой открытый проект, именуя переменные в стиле «ВерблюжийРегистр».
И только после того, как написал о нём статью, он узнал, что в питоне для имён переменных принято использовать подчёркивания для разделения слов (under_score). Нужно срочно всё исправить, пока его не «закидали тапками».

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

Задача 11. Удаление повторов

Довольно распространённая ошибка ошибка — это повтор слова.
Вот в предыдущем предложении такая допущена. Необходимо исправить каждый такой повтор (слово, один или несколько пробельных символов, и снова то же слово).

Задача 12. Близкие слова

Для простоты будем считать словом любую последовательность букв, цифр и знаков _ (то есть символов w).
Дан текст. Необходимо найти в нём любой фрагмент, где сначала идёт слово «олень», затем не более 5 слов, и после этого идёт слово «заяц».

Задача 13. Форматирование больших чисел

Большие целые числа удобно читать, когда цифры в них разделены на тройки запятыми.
Переформатируйте целые числа в тексте.

Задача 14. Разделить текст на предложения

Для простоты будем считать, что:

  • каждое предложение начинается с заглавной русской или латинской буквы;
  • каждое предложение заканчивается одним из знаков препинания .;!?;
  • между предложениями может быть любой непустой набор пробельных символов;
  • внутри предложений нет заглавных и точек (нет пакостей в духе «Мы любим творчество А. С. Пушкина)».

Разделите текст на предложения так, чтобы каждое предложение занимало одну строку.
Пустых строк в выводе быть не должно. Любые наборы из полее одного пробельного символа замените на один пробел.

Задача 15. Форматирование номера телефона

Если вы когда-нибудь пытались собирать номера мобильных телефонов, то наверняка знаете, что почти любые 10 человек используют как минимум пяток различных способов записать номер телефона. Кто-то начинает с +7, кто-то просто с 7 или 8, а некоторые вообще не пишут префикс. Трёхзначный код кто-то отделяет пробелами, кто-то при помощи дефиса, кто-то скобками (и после скобки ещё пробел некоторые добавляют). После следующих трёх цифр кто-то ставит пробел, кто-то дефис, кто-то ничего не ставит. И после следующих двух цифр — тоже. А некоторые начинают за здравие, а заканчивают… В общем очень неудобно!

На вход даётся номер телефона, как его мог бы ввести человек. Необходимо его переформатировать в формат +7 123 456-78-90. Если с номером что-то не так, то нужно вывести строчку Fail!.

Задача 16. Поиск e-mail’ов — 2

В предыдущей задаче мы немного схалтурили.
Однако к этому моменту задача должна стать посильной!

На вход даётся текст. Необходимо вывести все e-mail адреса, которые в нём встречаются. При этом e-mail не может быть частью слова, то есть слева и справа от e-mail’а должен быть либо конец строки, либо не-буква и при этом не один из символов '._+-, допустимых в адресе.

Post scriptum

PS. Текст длинный, в нём наверняка есть опечатки и ошибки. Пишите о них скорее в личку, я тут же исправлю.
PSS. Ух и намаялся я нормальный html в хабра-html перегонять. Кажется, парсер хабра писан на регулярках, иначе как объяснить все те странности, которые приходилось вылавливать бинпоиском? :)

In this tutorial, it’s shown how to find and validate phone numbers in Python using simple examples. We will review different phone number formats which are the most popular.

The best option for search and validation of data like phones numbers, zip codes, identifiers is Regular expression or Regex.

Next, we’ll see the examples to find, extract or validate phone numbers from a given text or string. The article starts with easy examples and finishes with advanced ones.

Step 1: Find Simple Phone Number

Let’s suppose that we need to validate simple phone number formats which don’t change. For example:

  • 000-000-000
re.findall(r"[d]{3}-[d]{3}-[d]{3}", text)
  • 000 000 0000
re.findall(r"[d]{3} [d]{3} [d]{3}", text)

The goal is to find all matches for the pattern.
The mentioned solution is very basic and it’s not working for numbers like:

  • 9000-000-0009 — it will find only 000-000-000
  • 000 000 000
  • (000)000-000

In order to deal with those cases the Regex should be improved.

Step 2: Regex for Phone Numbers with a Plus

Often phones numbers are displayed with plus sign like:

  • +000-000-000

This format is matched by next regular expression:

re.findall(r"+?[d]{3}-[d]{3}-[d]{3}", text)

Note that this will catch:

  • 000-000-000
  • +000-000-000

but also:

5000-000-0004 will be extracted as 000-000-000. In the next step we will solve this problem.

Step 3: Validate Phone Numbers for Exact Match

If the the format is important and only exact matches are needed like:
000-000-000, +000-000-000 but not — 5000-000-0004 , +000-000-0004 then we need to add word boundaries to our Regex by adding at the start and the end b:

re.findall(r"+?b[d]{3}-[d]{3}-[d]{3}b", text)

Next let’s see a more generic example which covers international and country phone numbers.

Step 4: Validate International Phone Number

It’s difficult to find and test international numbers with 100% accuracy. Analysis of the data might be needed in order to check what formats are present in the text.

One possible solution for validation of international numbers is:

re.match(r"^[+(]?d+(?:[- )(]+d+)+$", phone)

Another regular expression is:

re.match(r"^[+d]?(?:[d-.s()]*)$", phone)

Step 4: Validate US, UK, French phone numbers

For example let’s start with US phone numbers:

  • (000)000-0000
  • 000-000-0000
  • (000) 000-0000

can be done with next Regex:

re.match(r"^(([0-9]{3}) ?|[0-9]{3}-)[0-9]{3}-[0-9]{4}$", phone)

UK or GB numbers like:

  • +447222000000
  • +44 7222 000 000

can be searched and validated by:

^(?:0|+?44)s?(?:ds?){9,11}$

other possible solution for UK is: ^(+44s?7d{3}|(?07d{3})?)s?d{3}s?d{3}(s?#(d{4}|d{3}))?$

The next simple Regex will work for French numbers:

^(?:(?:+|00)33|0)s*[d](?:[s.-]*d{2}){4}$

like:

  • 00 00 00 00 00
  • +33 0 00 00 00 00

Step 5: Find phone numbers in different formats

If you like to build a Regex which find various formats you can try with the next one:

[+d]?(d{2,3}[-.s]??d{2,3}[-.s]??d{4}|(d{3})s*d{3}[-.s]??d{4}|d{3}[-.s]??d{4})

The one above will cover most phone numbers but will not work for all.

If the validation is important or additional features are needed like:

  • updates for new formats/countries/regions
  • geographical information related to a phone number
  • timezone information

then we will recommend mature libraries to be used. Good example in this case is the Google’s Java and JavaScript library for parsing, formatting, and validating international phone numbers.

Conclusion

Have in mind that Regex are powerful but you may face performance issues for the complex ones. Try to use simple and understandable Regex. Sometimes you may need to play with flags in order to make it work properly:

/^[(]?0([d{9})$/mg

Another important note is about using:

  • start and end — ^ and $
  • word boundaries — b

We covered most cases of phone validation by using python and Regex.

https://docs.python.org/3/library/re.html#re.findall

Findall returns lists of tuples, with each tuple representing the groups from one match. You are grouping the whitespaces but you’re not grouping the actual digits.

Try a regex that groups the digits too:

r"(+420)?(s*)?(d{3})(s*)?(d{3})(s*)?(d{3})"

E.g.

def detect_numbers(text):
    phone_regex = re.compile(r"(+420)?s*?(d{3})s*?(d{3})s*?(d{3})")
    print(phone_regex.findall(text))

detect_numbers("so I need to match +420 123 123 123, also 123 123 123, also +420123123123 and also 123123123. Can y")

prints:

[('+420', '123', '123', '123'), ('', '123', '123', '123'), ('+420', '123', '123', '123'), ('', '123', '123', '123')]

You could then string-join the group matches to get the numbers, e.g.

def detect_numbers(text):
    phone_regex = re.compile(r"(+420)?s*?(d{3})s*?(d{3})s*?(d{3})")
    groups = phone_regex.findall(text)
    for g in groups:
        print("".join(g))

detect_numbers("so I need to match +420 123 123 123, also 123 123 123, also +420123123123 and also 123123123. Can y")

prints:

+420123123123
123123123
+420123123123
123123123

В Python для работы с регулярными выражениями есть модуль re. Для использования его нужно импортировать. Рассмотрим простой пример поиска номера телефона:

>>> import re
>>> match = re.search('d{3}-d{3}-d{4}', 'Мой номер 495-456-9102')
>>> print('Найденный телефонный номер: ' + match.group())
Найденный телефонный номер: 495-456-9102

Если найдены совпадения, метод re.search() возвращает объект Match. Если совпадений нет — None.

Методы, которые предоставляет библиотека re:

  • re.match(pattern, string, [flags=0])
  • re.search(pattern, string, [flags=0])
  • re.findall(pattern, string, [flags=0])
  • re.split(pattern, string, [maxsplit=0], [flags=0])
  • re.sub(pattern, replace, string, [count=0], [flags=0])
  • re.compile(pattern, [flags=0])

Список метасимволов, которые поддерживает модуль re:

. ^ $ * + ? { } [ ] | ( )

Назначение метасимволов

  • . — Один любой символ, кроме новой строки n
  • ? — 0 или 1 вхождение шаблона слева
  • + — 1 и более вхождений шаблона слева
  • * — 0 и более вхождений шаблона слева
  • w — Любая цифра или буква (W — все, кроме буквы или цифры)
  • d — Любая цифра от 0 до 9 (D — все, кроме цифры)
  • s — Любой пробельный символ (S — любой непробельнй символ)
  • b — Граница слова
  • […] — Один из символов в скобках ([^…] — любой символ, кроме тех, что в скобках)
  • — Экранирование специальных символов (. означает точку или + — знак «плюс»)
  • ^ и $ — Начало и конец строки соответственно
  • {n,m} — От n до m вхождений ({n,}n и больше)
  • a|b — Соответствует a или b
  • (…) — Группирует выражение и возвращает найденный текст
  • t,n — Символ табуляции и новой строки соответственно

Создание групп с помощью круглых скобок:

>>> match = re.search('(d{3})-(d{3}-d{4})', 'Мой номер 495-456-9102')
>>> match.group()
'495-456-9102'
>>> match.group(0)
'495-456-9102'
>>> print('Код города: ' + match.group(1))
Код города: 495
>>> print('Номер телефона: ' + match.group(2))
Номер телефона: 456-9102

Если нужно извлечь сразу все группы:

>>> match = re.search('(d{3})-(d{3}-d{4})', 'Мой номер 495-456-9102')
>>> match.groups()
('495', '456-9102')
>>> code, number = match.groups()
>>> code
'495'
>>> number
'456-9102'

Метод re.search() находит только первое вхождение шаблона. Если нужно найти все вхождения, используйте метод re.findall():

>>> matches = re.findall('d{3}-d{3}-d{4}', 'Домашний 495-456-9102 или мобильный 926-123-4567')
>>> matches
['495-456-9102', '926-123-4567']

Поиск всех групп для всех совпадений шаблона:

>>> matches = re.findall('(d{3})-(d{3}-d{4})', 'Домашний 495-456-9102 или мобильный 926-123-4567')
>>> matches
[('495', '456-9102'), ('926', '123-4567')]
>>> matches[0][0]
'495'
>>> matches[1][1]
'123-4567'

Метод re.split() разделяет строку по заданному шаблону:

>>> re.split('n', 'First line.nSecond line.nThird line.')
['First line.', 'Second line.', 'Third line.']

Метод re.sub() ищет шаблон в строке и заменяет его на указанную подстроку. Если шаблон не найден, строка остается неизменной.

>>> re.sub('RoboCop', 'Робот-полицейский', 'RoboCop is part man, part machine, all cop.')
'Робот-полицейский is part man, part machine, all cop.'

В строке замены можно использовать обратные ссылки 1, 2, 3 и т.д.

>>> re.sub('(d{3})-(d{3}-d{4})', 'код города \1, номер телефона \2', 'Мой номер: 495-456-9102')
'Мой номер: код города 495, номер телефона 456-9102'

Метод re.match() ищет по заданному шаблону в начале строки.

>>> None == re.match('d{3}-d{3}-d{4}', '495-456-9102 Мой номер')
False
>>> None == re.match('d{3}-d{3}-d{4}', 'Мой номер 495-456-9102')
True

Метод re.compite() позволяет собрать регулярное выражение в отдельный объект, который может быть использован для поиска. Это также избавляет от переписывания одного и того же выражения.

regexp = re.compile('d{3}-d{3}-d{4}')
match = regexp.search('Мой номер 495-456-9102')
print('Найденный телефонный номер: ' + match.group())
Найденный телефонный номер: 495-456-9102

Флаги компиляции регулярных выражений

  • re.A или re.ASCII
  • re.DEBUG
  • re.I или re.IGNORECASE
  • re.L или re.LOCALE
  • re.M или re.MULTILINE
  • re.S или re.DOTALL
  • re.X или re.VERBOSE

Игнорирование регистра при поиске соответствий

>>> re.search('robocop', 'RoboCop is part man, part machine, all cop.', re.IGNORECASE).group()
'RoboCop'

Комбинации .* соответствует все, за исключением символа новой строки. С помощью re.DOTALL можно установить режим, при котором точке соответствует также символ новой строки.

>>> re.search('.*', 'First line.nSecond line.nThird line.').group()
'First line.'
>>> re.search('.*', 'First line.nSecond line.nThird line.', re.DOTALL).group()
'First line.nSecond line.nThird line.'

Если нужно использовать несколько флагов компиляции:

>>> regexp = re.compile('foo', re.DOTALL | re.IGNORECASE)

Флаг компиляции re.VERBOSE включает многословный режим, при котором пробелы и комментарии игнорируются.

# регулярное выражение для номера телефона
phoneRegex = re.compile('''
    (?:(?(d{3}))?)?             # код города
    (?:s|-)?                      # разделитель
    (d{3})                        # первые три цифры
    (?:s|-)?                      # разделитель
    (d{2})                        # еще две цифры
    (?:s|-)?                      # разделитель
    (d{2})                        # еще две цифры
    (?:s*доб[.а-я]*s*(d{2,5}))? # добавочный
    ''', re.VERBOSE)

# регулярное выражение для адреса эл.почты
emailRegex = re.compile('''
    [a-z0-9._-]+     # имя пользователя
    @                # @
    [a-z0-9.-]+      # первая часть домена
    .[a-z]{2,6}     # вторая часть домена
    ''', re.VERBOSE | re.IGNORECASE)

Поиск:
Python • RegExp • Модуль • Шаблон

Каталог оборудования

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Производители

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Функциональные группы

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Prerequisite: Python RegEx

You may be familiar with searching for text by pressing ctrl-F and typing in the words you’re looking for. Regular expressions go one step further: They allow you to specify a pattern of text to search for.
Regular expressions, called regexes for short, are descriptions for a pattern of text. For example, a d in a regex stands for a digit character — that is, any single numeral 0 to 9.

  • Following regex is used in Python to match a string of three numbers, a hyphen, three more numbers, another hyphen, and four numbers.
    Any other string would not match the pattern.
    ddd-ddd-dddd
  • Regular expressions can be much more sophisticated. For example, adding a 3 in curly brackets ({3}) after a pattern is like saying, “ Match this pattern three times.” So the slightly shorter regex
    d{3}-d{3}-d{4}

    (It matches the correct phone number format.)

Creating Regex object

All the regex functions in Python are in the re module

import re

To create a Regex object that matches the phone number pattern, enter the following into the interactive shell.

phoneNumRegex = re.compile(r'ddd-ddd-dddd')

Now the phoneNumRegex variable contains a Regex object.

Matching regex objects

A Regex object’s search() method searches the string it is passed for any matches to the regex. Match objects have a group() method that will return the actual matched text from the searched string.

import re

phoneNumRegex = re.compile(r'ddd-ddd-dddd')

mo = phoneNumRegex.search('My number is 415-555-4242.')

print('Phone number found: ' + mo.group())

Output:

Phone number found: 415-555-4242

Steps of Regular Expression Matching

While there are several steps to using regular expressions in Python, each step is fairly simple.

  1. Import the regex module with import re.
  2. Create a Regex object with the re.compile() function. (Remember to use a raw string.)
  3. Pass the string you want to search into the Regex object’s search() method. This returns a Match object.
  4. Call the Match object’s group() method to return a string of the actual matched text.
  5. Grouping with parentheses

    1. Matching objects:Say you want to separate the area code from the rest of the phone number. Adding parentheses will create groups in the regex: (ddd)-(ddd-dddd). Then you can use the group() match object method to grab the matching text from just one group.

      import re

      phoneNumRegex = re.compile(r'(ddd)-(ddd-dddd)')

      mo = phoneNumRegex.search('My number is 415-555-4242.')

      print(mo.group(1))

      OUTPUT:

      '415'
      
    2. Retrieve all the groups at once : If you would like to retrieve all the groups at once, use the groups(), method—note the plural form for the name.

      import re

      phoneNumRegex = re.compile(r'(ddd)-(ddd-dddd)')

      mo = phoneNumRegex.search('My number is 415-555-4242.')

      print(mo.groups())

      OUTPUT:

      ('415', '555-4242')
    3. Using mo.groups : mo.groups() will return a tuple of multiple values, you can use the multiple-assignment trick to assign each value to a separate variable, as in the following areaCode, mainNumber = mo.groups() line.

      import re

      phoneNumRegex = re.compile(r'(ddd)-(ddd-dddd)')

      mo = phoneNumRegex.search('My number is 415-555-4242.')

      areaCode, mainNumber = mo.groups()

      print(mainNumber)

      OUTPUT:

      '555-4242'
    4. Match a parenthesis : Parentheses have a special meaning in regular expressions, but what do you do if you need to match a parenthesis in your text. For instance, maybe the phone numbers you are trying to match have the area code set in parentheses. In this case, you need to escape the ( and ) characters with a backslash. Enter the following into the interactive shell:

      import re

      phoneNumRegex = re.compile(r'((ddd)) (ddd-dddd)')

      mo = phoneNumRegex.search('My phone number is (415) 555-4242.')

      print(mo.group(1))

      OUTPUT:

      '(415)'

      The ( and ) escape characters in the raw string passed to re.compile() will match actual parenthesis characters.

    Matching Multiple Groups with the Pipe

    The | character is called a pipe. You can use it anywhere you want to match one of many expressions. For example, the regular expression r’Batman|Tina Fey’ will match either ‘Batman’ or ‘Tina Fey’.

    When both Batman and Tina Fey occur in the searched string, the first occurrence of matching text will be returned as the Match object. Enter the following into the interactive shell:

    import re

    heroRegex = re.compile (r'Batman|Tina Fey')

    mo1 = heroRegex.search('Batman and Tina Fey.')

    print(mo1.group())

    OUTPUT:

    'Batman'

    Matching Specific Repetitions with Curly Brackets

    If you have a group that you want to repeat a specific number of times, follow the group in your regex with a number in curly brackets. For example, the regex (Ha){3} will match the string ‘HaHaHa’, but it will not match ‘HaHa’, since the latter has only two repeats of the (Ha) group.

    Instead of one number, you can specify a range by writing a minimum, a comma, and a maximum in between the curly brackets. For example, the regex (Ha){3, 5} will match ‘HaHaHa’, ‘HaHaHaHa’, and ‘HaHaHaHaHa’.

    You can also leave out the first or second number in the curly brackets to leave the minimum or maximum unbounded. For example, (Ha){3, } will match three or more instances of the (Ha) group, while (Ha){, 5} will match zero to five instances. Curly brackets can help make your regular expressions shorter. These two regular expressions match identical patterns:

    (Ha){3}
    (Ha)(Ha)(Ha)

    And these two regular expressions also match identical patterns:

    (Ha){3, 5}
    ((Ha)(Ha)(Ha))|((Ha)(Ha)(Ha)(Ha))|((Ha)(Ha)(Ha)(Ha)(Ha))

    Enter the following into the interactive shell:

    import re

    haRegex = re.compile(r'(Ha){3}')

    mo1 = haRegex.search('HaHaHa')

    print(mo1.group())

    OUTPUT:

    'HaHaHa'

    import re

    haRegex = re.compile(r'(Ha){3}')

    mo2 = haRegex.search('Ha')== None

    print(mo2)

    OUTPUT:

    True
    

    Here, (Ha){3} matches ‘HaHaHa’ but not ‘Ha’. Since it doesn’t match ‘Ha’, search() returns None.

    Optional Matching with the Question Mark

    Sometimes there is a pattern that you want to match only optionally. That is, the regex should find a match whether or not that bit of text is there. The ? character flags the group that precedes it as an optional part of the pattern. For example, enter the following into the interactive shell:

    import re

    batRegex = re.compile(r'Bat(wo)?man')

    mo1 = batRegex.search('The Adventures of Batman')

    print(mo1.group())

    OUTPUT:

    'Batman'

    import re

    batRegex = re.compile(r'Bat(wo)?man')

    mo2 = batRegex.search('The Adventures of Batwoman')

    print(mo2.group())

    OUTPUT:

    'Batwoman'

    The (wo)? part of the regular expression means that the pattern wo is an optional group. The regex will match text that has zero instances or one instance of wo in it. This is why the regex matches both ‘Batwoman’ and ‘Batman’.
    You can think of the ? as saying, “Match zero or one of the group preceding this question mark.”
    If you need to match an actual question mark character, escape it with ?.

    Matching Zero or More with the Star

    The * (called the star or asterisk) means “match zero or more”—the group that precedes the star can occur any number of times in the text. It can be completely absent or repeated over and over again. Let’s look at the Batman example again.

    import re

    batRegex = re.compile(r'Bat(wo)*man')

    mo1 = batRegex.search('The Adventures of Batman')

    print(mo1.group())

    OUTPUT:

    'Batman'

    import re

    batRegex = re.compile(r'Bat(wo)*man')

    mo2 = batRegex.search('The Adventures of Batwoman')

    print(mo2.group())

    OUTPUT:

    'Batwoman'

    import re

    batRegex = re.compile(r'Bat(wo)*man')

    mo3 = batRegex.search('The Adventures of Batwowowowoman')

    print(mo3.group())

    OUTPUT:

    'Batwowowowoman'

    For ‘Batman’, the (wo)* part of the regex matches zero instances of wo in the string; for ‘Batwoman’, the (wo)* matches one instance of wo; and for ‘Batwowowowoman’, (wo)* matches four instances of wo.

    If you need to match an actual star character, prefix the star in the regular expression with a backslash, *.

    Matching One or More with the Plus

    While * means “match zero or more, ” the + (or plus) means “match one or more.” Unlike the star, which does not require its group to appear in the matched string, the group preceding a plus must appear at least once. It is not optional. Enter the following into the interactive shell, and compare it with the star regexes in the previous section:

    import re

    batRegex = re.compile(r'Bat(wo)+man')

    mo1 = batRegex.search('The Adventures of Batwoman')

    print(mo1.group())

    OUTPUT:

    'Batwoman'

    import re

    batRegex = re.compile(r'Bat(wo)+man')

    mo2 = batRegex.search('The Adventures of Batwowowowoman')

    print(mo2.group())

    OUTPUT:

    'Batwowowowoman'

    batRegex = re.compile(r’Bat(wo)+man’)

    import re

    batRegex = re.compile(r'Bat(wo)+man')

    mo3 = batRegex.search('The Adventures of Batman')== None

    print(mo3)

    OUTPUT:

    True

    The regex Bat(wo)+man will not match the string ‘The Adventures of Batman’ because at least one wo is required by the plus sign.

    If you need to match an actual plus sign character, prefix the plus sign with a backslash to escape it: +.

Prerequisite: Python RegEx

You may be familiar with searching for text by pressing ctrl-F and typing in the words you’re looking for. Regular expressions go one step further: They allow you to specify a pattern of text to search for.
Regular expressions, called regexes for short, are descriptions for a pattern of text. For example, a d in a regex stands for a digit character — that is, any single numeral 0 to 9.

  • Following regex is used in Python to match a string of three numbers, a hyphen, three more numbers, another hyphen, and four numbers.
    Any other string would not match the pattern.
    ddd-ddd-dddd
  • Regular expressions can be much more sophisticated. For example, adding a 3 in curly brackets ({3}) after a pattern is like saying, “ Match this pattern three times.” So the slightly shorter regex
    d{3}-d{3}-d{4}

    (It matches the correct phone number format.)

Creating Regex object

All the regex functions in Python are in the re module

import re

To create a Regex object that matches the phone number pattern, enter the following into the interactive shell.

phoneNumRegex = re.compile(r'ddd-ddd-dddd')

Now the phoneNumRegex variable contains a Regex object.

Matching regex objects

A Regex object’s search() method searches the string it is passed for any matches to the regex. Match objects have a group() method that will return the actual matched text from the searched string.

import re

phoneNumRegex = re.compile(r'ddd-ddd-dddd')

mo = phoneNumRegex.search('My number is 415-555-4242.')

print('Phone number found: ' + mo.group())

Output:

Phone number found: 415-555-4242

Steps of Regular Expression Matching

While there are several steps to using regular expressions in Python, each step is fairly simple.

  1. Import the regex module with import re.
  2. Create a Regex object with the re.compile() function. (Remember to use a raw string.)
  3. Pass the string you want to search into the Regex object’s search() method. This returns a Match object.
  4. Call the Match object’s group() method to return a string of the actual matched text.
  5. Grouping with parentheses

    1. Matching objects:Say you want to separate the area code from the rest of the phone number. Adding parentheses will create groups in the regex: (ddd)-(ddd-dddd). Then you can use the group() match object method to grab the matching text from just one group.

      import re

      phoneNumRegex = re.compile(r'(ddd)-(ddd-dddd)')

      mo = phoneNumRegex.search('My number is 415-555-4242.')

      print(mo.group(1))

      OUTPUT:

      '415'
      
    2. Retrieve all the groups at once : If you would like to retrieve all the groups at once, use the groups(), method—note the plural form for the name.

      import re

      phoneNumRegex = re.compile(r'(ddd)-(ddd-dddd)')

      mo = phoneNumRegex.search('My number is 415-555-4242.')

      print(mo.groups())

      OUTPUT:

      ('415', '555-4242')
    3. Using mo.groups : mo.groups() will return a tuple of multiple values, you can use the multiple-assignment trick to assign each value to a separate variable, as in the following areaCode, mainNumber = mo.groups() line.

      import re

      phoneNumRegex = re.compile(r'(ddd)-(ddd-dddd)')

      mo = phoneNumRegex.search('My number is 415-555-4242.')

      areaCode, mainNumber = mo.groups()

      print(mainNumber)

      OUTPUT:

      '555-4242'
    4. Match a parenthesis : Parentheses have a special meaning in regular expressions, but what do you do if you need to match a parenthesis in your text. For instance, maybe the phone numbers you are trying to match have the area code set in parentheses. In this case, you need to escape the ( and ) characters with a backslash. Enter the following into the interactive shell:

      import re

      phoneNumRegex = re.compile(r'((ddd)) (ddd-dddd)')

      mo = phoneNumRegex.search('My phone number is (415) 555-4242.')

      print(mo.group(1))

      OUTPUT:

      '(415)'

      The ( and ) escape characters in the raw string passed to re.compile() will match actual parenthesis characters.

    Matching Multiple Groups with the Pipe

    The | character is called a pipe. You can use it anywhere you want to match one of many expressions. For example, the regular expression r’Batman|Tina Fey’ will match either ‘Batman’ or ‘Tina Fey’.

    When both Batman and Tina Fey occur in the searched string, the first occurrence of matching text will be returned as the Match object. Enter the following into the interactive shell:

    import re

    heroRegex = re.compile (r'Batman|Tina Fey')

    mo1 = heroRegex.search('Batman and Tina Fey.')

    print(mo1.group())

    OUTPUT:

    'Batman'

    Matching Specific Repetitions with Curly Brackets

    If you have a group that you want to repeat a specific number of times, follow the group in your regex with a number in curly brackets. For example, the regex (Ha){3} will match the string ‘HaHaHa’, but it will not match ‘HaHa’, since the latter has only two repeats of the (Ha) group.

    Instead of one number, you can specify a range by writing a minimum, a comma, and a maximum in between the curly brackets. For example, the regex (Ha){3, 5} will match ‘HaHaHa’, ‘HaHaHaHa’, and ‘HaHaHaHaHa’.

    You can also leave out the first or second number in the curly brackets to leave the minimum or maximum unbounded. For example, (Ha){3, } will match three or more instances of the (Ha) group, while (Ha){, 5} will match zero to five instances. Curly brackets can help make your regular expressions shorter. These two regular expressions match identical patterns:

    (Ha){3}
    (Ha)(Ha)(Ha)

    And these two regular expressions also match identical patterns:

    (Ha){3, 5}
    ((Ha)(Ha)(Ha))|((Ha)(Ha)(Ha)(Ha))|((Ha)(Ha)(Ha)(Ha)(Ha))

    Enter the following into the interactive shell:

    import re

    haRegex = re.compile(r'(Ha){3}')

    mo1 = haRegex.search('HaHaHa')

    print(mo1.group())

    OUTPUT:

    'HaHaHa'

    import re

    haRegex = re.compile(r'(Ha){3}')

    mo2 = haRegex.search('Ha')== None

    print(mo2)

    OUTPUT:

    True
    

    Here, (Ha){3} matches ‘HaHaHa’ but not ‘Ha’. Since it doesn’t match ‘Ha’, search() returns None.

    Optional Matching with the Question Mark

    Sometimes there is a pattern that you want to match only optionally. That is, the regex should find a match whether or not that bit of text is there. The ? character flags the group that precedes it as an optional part of the pattern. For example, enter the following into the interactive shell:

    import re

    batRegex = re.compile(r'Bat(wo)?man')

    mo1 = batRegex.search('The Adventures of Batman')

    print(mo1.group())

    OUTPUT:

    'Batman'

    import re

    batRegex = re.compile(r'Bat(wo)?man')

    mo2 = batRegex.search('The Adventures of Batwoman')

    print(mo2.group())

    OUTPUT:

    'Batwoman'

    The (wo)? part of the regular expression means that the pattern wo is an optional group. The regex will match text that has zero instances or one instance of wo in it. This is why the regex matches both ‘Batwoman’ and ‘Batman’.
    You can think of the ? as saying, “Match zero or one of the group preceding this question mark.”
    If you need to match an actual question mark character, escape it with ?.

    Matching Zero or More with the Star

    The * (called the star or asterisk) means “match zero or more”—the group that precedes the star can occur any number of times in the text. It can be completely absent or repeated over and over again. Let’s look at the Batman example again.

    import re

    batRegex = re.compile(r'Bat(wo)*man')

    mo1 = batRegex.search('The Adventures of Batman')

    print(mo1.group())

    OUTPUT:

    'Batman'

    import re

    batRegex = re.compile(r'Bat(wo)*man')

    mo2 = batRegex.search('The Adventures of Batwoman')

    print(mo2.group())

    OUTPUT:

    'Batwoman'

    import re

    batRegex = re.compile(r'Bat(wo)*man')

    mo3 = batRegex.search('The Adventures of Batwowowowoman')

    print(mo3.group())

    OUTPUT:

    'Batwowowowoman'

    For ‘Batman’, the (wo)* part of the regex matches zero instances of wo in the string; for ‘Batwoman’, the (wo)* matches one instance of wo; and for ‘Batwowowowoman’, (wo)* matches four instances of wo.

    If you need to match an actual star character, prefix the star in the regular expression with a backslash, *.

    Matching One or More with the Plus

    While * means “match zero or more, ” the + (or plus) means “match one or more.” Unlike the star, which does not require its group to appear in the matched string, the group preceding a plus must appear at least once. It is not optional. Enter the following into the interactive shell, and compare it with the star regexes in the previous section:

    import re

    batRegex = re.compile(r'Bat(wo)+man')

    mo1 = batRegex.search('The Adventures of Batwoman')

    print(mo1.group())

    OUTPUT:

    'Batwoman'

    import re

    batRegex = re.compile(r'Bat(wo)+man')

    mo2 = batRegex.search('The Adventures of Batwowowowoman')

    print(mo2.group())

    OUTPUT:

    'Batwowowowoman'

    batRegex = re.compile(r’Bat(wo)+man’)

    import re

    batRegex = re.compile(r'Bat(wo)+man')

    mo3 = batRegex.search('The Adventures of Batman')== None

    print(mo3)

    OUTPUT:

    True

    The regex Bat(wo)+man will not match the string ‘The Adventures of Batman’ because at least one wo is required by the plus sign.

    If you need to match an actual plus sign character, prefix the plus sign with a backslash to escape it: +.

  • #1

У меня есть строка, в которой хранится номер телефона. Мне надо проверить, соответствует ли данная строка регулярному вырежению ^((+?7|8)[ -] ?)?(((d{3}))|(d{3}))?([ -])?(d{3}[- ]?d{2}[- ]?d{2})$

  • #2

Python:

import re

a = '8-900-800-10-20'
r = re.compile('^((+?7|8)[ -] ?)?(((d{3}))|(d{3}))?([ -])?(d{3}[- ]?d{2}[- ]?d{2})$')

if r.search(a):
    print('соответствует')
else:
    print('не соответствует')

  • #3

Python:

import re

a = '8-900-800-10-20'
r = re.compile('^((+?7|8)[ -] ?)?(((d{3}))|(d{3}))?([ -])?(d{3}[- ]?d{2}[- ]?d{2})$')

if r.search(a):
    print('соответствует')
else:
    print('не соответствует')

А данная регулярка подходит для проверки номера в python? Я ввожу 8916202 и у меня всё принимается

  • #4

А данная регулярка подходит для проверки номера в python? Я ввожу 8916202 и у меня всё принимается

это проблема с регуляркой…
попробуйте такую

Код:

r = re.compile('^+7|8D*d{3}D*d{3}D*d{2}D*d{2}')

  • #5

вот такая лучше

Python:

r = re.compile('(+7|8)D*d{3}D*d{3}D*d{2}D*d{2}')

  • #6

Всё получилось, спасибо. А регулярку для номера авто не подскажите?

Последнее редактирование: Мар 21, 2021

  • #9

так можно

Python:

r = re.compile('[а-я]{1}d{3}[а-я]{2}d{2}[а-я]{3}')

в номерах не все буквы используются вроде, можно в квадратных скобках их указать вместо а-я…

Поиск совпадающих строк с Python и Regex. Часть 1

Возможно, вы знакомы с поиском текста, нажимая CTRL-F и вводя искомые слова. Регулярные выражения идут еще дальше: они позволяют указать образец текста для поиска. Вы можете не знать точный номер телефона компании, но если вы живете в Соединенных Штатах или Канаде, вы знаете, что это будут три цифры, за которыми следует дефис, а затем еще четыре цифры (и, при желании, трехзначный код города на начало). Вот как вы, как человек, узнаете номер телефона, когда видите его: 415-555-1234 — это номер телефона, а 4,155,551,234 — нет.

Мы также ежедневно распознаем всевозможные другие текстовые шаблоны: адреса электронной почты имеют символы @ в середине, номера социального страхования США состоят из девяти цифр и двух дефисов, URL-адреса веб-сайтов часто имеют точку и косую черту, в заголовках новостей используется регистр заголовка, хэштеги в социальных сетях начинаются с символа # и не содержат пробелов и т. д.

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

Поиск шаблонов текста без регулярных выражений.

Допустим, вы хотите найти в строке американский номер телефона. Если вы американец, то вы знаете схему: три числа, дефис, три числа, дефис и четыре числа. Вот пример: 415-555-4242.

Давайте воспользуемся функцией isPhoNumber(), чтобы проверить, соответствует ли строка этому шаблону, вернув True или False. Откройте новую вкладку редактора файлов и введите следующий код; затем сохраните файл как isPhoNumber.py:


def isPhoNumber(phon):
  if len(phon) != 12:
       return False
  for i in range(0, 3):
    if not phon[i].isdecimal():
      return False

           
  if phon[3] != '-':
       return False
  for i in range(4, 7):
    if not phon[i].isdecimal():
      return False

           
  if phon[7] != '-':
       return False
  for i in range(8, 12):
    if not phon[i].isdecimal():
      return False
  return True

print('Is 415-555-4242 a phone number?')
print(isPhoNumber('415-555-4242'))
print('Is Mike a phone number?')
print(isPhoNumber('Is Mike'))

Результат:


Is 415-555-4242 a phone number?
True
Is Mike a phone number?
False

Функция isPhoNumber() имеет код, который выполняет несколько проверок, чтобы узнать, является ли строка в тексте допустимым номером телефона. Если какая-либо из этих проверок не удалась, функция вернет False. Сначала код проверяет, что строка состоит ровно из 12 символов. Затем он проверяет, что код города (то есть первые три символа в тексте) состоит только из цифровых символов. Остальная часть функции проверяет, соответствует ли строка шаблону телефонного номера: номер должен иметь первый дефис после кода зоны, еще три цифровых символа, затем еще один дефис и, наконец, еще четыре цифры . Если выполнение программы удается пройти все проверки, возвращается True.

Если вы хотите найти номер телефона в более крупной строке, вам придется добавить еще больше кода, чтобы найти шаблон номера телефона. Замените четыре последних вызова функции print() в isPhoNumber.py следующими:


message = 'Перезвоните на номер 415-555-1011. 415-555-9999 мой офисный номер.'

for i in range(len(message)):

  
  chunk = message[i:i+12]

  
  if isPhoneNumber(chunk):

 
       print('Найден номер телефона: ' + chunk)

print('Готово')

Когда эта программа будет запущена, результат будет выглядеть так:


Найден номер телефона: 415-555-1011
Найден номер телефона: 415-555-9999
Готово

На каждой итерации цикла for новый фрагмент из 12 символов из сообщения присваивается переменной chunk.

Хотя в этом примере строка в сообщении короткая, она может состоять из миллионов символов, и программа все равно будет работать менее чем за секунду. Аналогичная программа, которая находит телефонные номера с помощью регулярных выражений, также будет работать менее чем за секунду, но регулярные выражения позволяют быстрее писать эти программы.

Поиск шаблонов текста с помощью регулярных выражений

Предыдущая программа поиска телефонных номеров работает, но в ней используется много кода для выполнения чего-то ограниченного: функция isPhoNumber() состоит из 17 строк, но может найти только один шаблон телефонных номеров. Как насчет номера телефона в формате 415.555.4242 или (415) 555-4242? Что, если бы у номера телефона был добавочный номер, например 415-555-4242 x99? Функция isPhoNumber() не сможет их проверить. Вы можете добавить еще больше кода для этих дополнительных шаблонов, но есть более простой способ.

Регулярные выражения, для краткости именуемые regex, представляют собой описания шаблона текста. Например, d в регулярном выражении обозначает цифровой символ, то есть любую отдельную цифру от 0 до 9. Регулярное выражение d d d- d d d- d d d d используется Python для сопоставления с тем же текстовым шаблоном, что и предыдущая функция isPhoNumber(): строка из трех чисел, дефис, еще три числа, еще один дефис и четыре числа. Любая другая строка не будет соответствовать регулярному выражению d d d- d d d- d d d d.

Но регулярные выражения могут быть намного сложнее. Например, добавление 3 в фигурных скобках ({3}) после шаблона — все равно что сказать: «Сопоставьте этот шаблон три раза». Таким образом, несколько более короткое регулярное выражение d {3} — d {3} — d {4} также соответствует правильному формату номера телефона.

Создание объектов Regex

Все функции регулярных выражений в Python находятся в модуле re. Введите в интерактивную оболочку следующее, чтобы импортировать этот модуль:


import re

Передача строкового значения, представляющего ваше регулярное выражение, в re.compile() возвращает объект шаблона Regex(или просто объект Regex).

Чтобы создать объект Regex, соответствующий шаблону номера телефона, введите в интерактивную оболочку следующее. (Помните, что d означает «цифровой символ», а d d d- d d d- d d d d — регулярное выражение для шаблона номера телефона.)


phoneNumRegex = re.compile(r'ddd-ddd-dddd')

Теперь переменная phoneNumRegex содержит объект Regex.

Соответствие объектов Regex.

Метод search() объекта Regex ищет в переданной строке любые совпадения с регулярным выражением. Метод search() вернет None, если шаблон регулярного выражения не найден в строке. Если шаблон найден, метод search() возвращает объект Match, у которого есть метод group(), который вернет фактический совпавший текст из искомой строки. Например, введите в интерактивную оболочку следующее:


 phoneNumRegex = re.compile(r'ddd-ddd-dddd')
 mo = phoneNumRegex.search('My number is 415-555-4242.')
 print('Phone number found: ' + mo.group())

Phone number found: 415-555-4242

Имя переменной mo — это просто общее имя, используемое для объектов Match. Этот пример сначала может показаться сложным, но он намного короче, чем предыдущая программа isPhoNumber.py, и делает то же самое.

Здесь мы передаем желаемый шаблон в re.compile() и сохраняем полученный объект Regex в phoneNumRegex. Затем мы вызываем search() в phoneNumRegex и передаем search() строку, которую мы хотим сопоставить во время поиска. Результат поиска сохраняется в переменной mo. В этом примере мы знаем, что наш шаблон будет найден в строке, поэтому мы знаем, что будет возвращен объект Match. Зная, что mo содержит объект Match, а не нулевое значение None, мы можем вызвать group() на mo, чтобы вернуть совпадение. Запись mo.group() внутри нашего вызова функции print() отображает полное совпадение, 415-555-4242.

Заключение

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

Импортируем модуль регулярного выражения с помощью import re.

Создаем объект Regex с помощью функции re.compile(). (Не забудьте использовать необработанную строку — r’строка’.)

Передадим строку, которую хотим найти, в метод search() объекта Regex. Это возвращает объект Match.

Вызовем метод group() объекта Match, чтобы вернуть строку фактического сопоставленного текста.

Хотя мы и можем тестировать код в интерактивной оболочке, нам также следует использовать веб-тестеры регулярных выражений, которые могут показать, как именно регулярное выражение соответствует введенному нами фрагменту текста. Один из них находится на здесь.

  • Создано 03.08.2021 10:37:18


  • Михаил Русаков

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

Понравилась статья? Поделить с друзьями:
  • Регистратура упорово больница номер телефона
  • Регистратура шемышейка больница номер телефона
  • Регистратура црб кяхта номер телефона
  • Регулярное выражение для номера телефона php
  • Регистратура улу теляк больница номер телефона