Функции для работы с регулярками живут в модуле re
. Основные функции:
Функция | Её смысл |
---|---|
re.search(pattern, string) |
Найти в строке string первую строчку, подходящую под шаблон pattern ; |
re.fullmatch(pattern, string) |
Проверить, подходит ли строка string под шаблон pattern ; |
re.split(pattern, string, maxsplit=0) |
Аналог str.split() , только разделение происходит по подстрокам, подходящим под шаблон pattern ; |
re.findall(pattern, string) |
Найти в строке string все непересекающиеся шаблоны pattern ; |
re.finditer(pattern, string) |
Итератор всем непересекающимся шаблонам pattern в строке string (выдаются match -объекты); |
re.sub(pattern, repl, string, count=0) |
Заменить в строке string все непересекающиеся шаблоны pattern на repl ; |
import re
match = re.search(r'\d\d\D\d\d', r'Телефон 123-12-12')
print(match[0] if match else 'Not found')
# -> 23-12
match = re.search(r'\d\d\D\d\d', r'Телефон 1231212')
print(match[0] if match else 'Not found')
# -> Not found
match = re.fullmatch(r'\d\d\D\d\d', r'12-12')
print('YES' if match else 'NO')
# -> YES
match = re.fullmatch(r'\d\d\D\d\d', r'Т. 12-12')
print('YES' if match else 'NO')
# -> NO
print(re.split(r'\W+', 'Где, скажите мне, мои очки??!'))
# -> ['Где', 'скажите', 'мне', 'мои', 'очки', '']
print(re.findall(r'\d\d\.\d\d\.\d{4}',
r'Эта строка написана 19.01.2018, а могла бы и 01.09.2017'))
# -> ['19.01.2018', '01.09.2017']
for m in re.finditer(r'\d\d\.\d\d\.\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'\d\d\.\d\d\.\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
, что несколько изменит режим работы регулярок. В качестве значения нужно передать сумму выбранных констант, вот они: Константа | Её смысл |
---|---|
re.ASCII |
По умолчанию \w , \W , \b , \B , \d , \D , \s , \S соответствуют все юникодные символы с соответствующим качеством. Например, \d соответствуют не только арабские цифры, но и вот такие: ٠١٢٣٤٥٦٧٨٩. re.ASCII ускоряет работу, если все соответствия лежат внутри ASCII. |
re.IGNORECASE |
Не различать заглавные и маленькие буквы. Работает медленнее, но иногда удобно |
re.MULTILINE |
Специальные символы ^ и $ соответствуют началу и концу каждой строки |
re.DOTALL |
По умолчанию символ \n конца строки не подходит под точку. С этим флагом точка — вообще любой символ |
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']
(?:...)
и перечисления |
Чтобы проверить, удовлетворяет ли строка хотя бы одному из шаблонов, можно воспользоваться аналогом оператора 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}
Также скобки (?:...)
позволяют локализовать часть шаблона, внутри которого происходит перечисление. Например, шаблон (?:он|тот) (?:шёл|плыл)
соответствует каждой из строк «он шёл», «он плыл», «тот шёл», «тот плыл», и является синонимом он шёл|он плыл|тот шёл|тот плыл
.
Шаблон | Применяем к тексту |
---|---|
(?:\w\w\d\d)+ |
Есть миг29а, ту154б. Некоторые делают даже миг29ту154ил86. |
(?:\w+\d+)+ |
Есть миг29а, ту154б. Некоторые делают даже миг29ту154ил86. |
(?:\+7|8)(?:-\d{2,3}){4} |
+7-926-123-12-12, 8-926-123-12-12 |
(?:[Хх][аоеи]+)+ |
Муха — хахахехо, ну хааахооохе, да хахахехохииии! Хам трамвайный. |
\b(?:[Хх][аоеи]+)+\b |
Муха — хахахехо, ну хааахооохе, да хахахехохииии! Хам трамвайный. |