Как использовать регулярные выражения в Python. Примеры для новичков

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

Именно поэтому возник такой высокий спрос вокруг изучения регулярных выражений. Ниже мы рассмотрим примеры их использования. Они часто применяются в разных языках программирования – C++, Perl, Java. Мы же рассмотрим примеры их использования на языке Pythone.

Регулярные выражения – что это? Как их использовать?

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

Регулярные выражения применяют 2 типа символов:

  1. Специальные (по названию понятно, что у них есть специальные значения, о которых вы узнаете ниже).
  2. Литералы (к примеру: 1, 2, a, b и так далее).

Программисты, работают с регулярными выражения в Python используется модуль re. Для его использования необходимо импортировать:

import re

В большинстве случаев регулярные выражения применяются для:

  • замены части строки;
  • разбивание строки на подстроки;
  • поиск в строке.

Методы

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

  • re.match()
  • re.findall()
  • re.search()
  • re.split()
  • re.compile()
  • re.sub()

Остановимся на каждом детально.

re.match(pattern, string)

Данный метод ищет по указанному шаблону в начале строки. К примеру, если вызвать метод match() на строке «AV Analytics AV» с шаблоном «AV», то он будет завершен успешно. Но если искать «Analytics», результат станет отрицательным. Пример:

import re
result = re.match(r’AV’, ‘AV Analytics Vidhya AV’)
print result

Результат:

<_sre.SRE_Match object at 0x0000000009BE4370>
Искомпая подстрока найдена. Для того чтобы вывести ее содержимое, применяем метод group().
result = re.match(r’AV’, ‘AV Analytics Vidhya AV’)
print result.group(0)

Результат:

AV
Найдем «Analytics» в этой строке. Метод вернет None, так как она начинается на «AV»:
result = re.match(r’Analytics’, ‘AV Analytics Vidhya AV’)
print result

Результат:

None

Чтобы узнать начальную/конечную позицию найденной строки используются методы start() и end().

result = re.match(r’AV’, ‘AV Analytics Vidhya AV’)
print result.start()
print result.end()

Результат:

0
2

Иногда такие методы оказываются весьма полезными при работе со строками.

re.search(pattern, string)

Данный метод схож с match(), однако он ищет не только в начале строки. Если мы попробуем найти «Analytics», то search() вернет объект, в отличие от предыдущего.

result = re.search(r’Analytics’, ‘AV Analytics Vidhya AV’)
print result.group(0)

Результат:

Analytics

Несмотря на то, что метод search() ищет по всей строке, он возвращается исключительно в первое совпадение, которое было им обнаружено.

re.findall(pattern, string)

Метод findall() возвращает все найденные совпадения. У него нет ограничение на поиск в конце или в начале строки. Поэтому если вы будете искать «AV» в нашей строке, метод вернет все его вхождения. Для поиска лучше использовать именно метод findall(), поскольку он может работать как re.match() и re.search().

result = re.findall(r’AV’, ‘AV Analytics Vidhya AV’)
print result

Результат:

[‘AV’, ‘AV’]

re.split(pattern, string, [maxsplit=0])

Данный метод разделяет строку по указанному шаблону.

result = re.split(r’y’, ‘Analytics’)
print result

Результат:

[‘Anal’, ‘tics’]

В нашем примере разделено слово «Analytics» по букве «y». Также метод split() принимает аргумент maxsplit со значением 0 (по умолчанию). В таком случае он разделит строку столько раз, сколько это возможно, если это условия не будет задано. Обратите внимание на примеры:

result = re.split(r’i’, ‘Analytics Vidhya’)
print result

Результат:

[‘Analyt’, ‘cs V’, ‘dhya’] # все возможные участки.
result = re.split(r’i’, ‘Analytics Vidhya’,maxsplit=1)
print result

Результат:

[‘Analyt’, ‘cs Vidhya’]

В примере параметр maxsplit = 1, поэтому строка разделилась на 2 части, а не на 3.

re.sub(pattern, repl, string)

Такой метод ищет шаблон в строке, после чего заменяет его на заданную подстроку. В том случае, если шаблон не найден, строка не меняется.

result = re.sub(r’India’, ‘the World’, ‘AV is largest Analytics community of India’)
print result

Результат:

‘AV is largest Analytics community of the World’

re.compile(pattern, repl, string)

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

pattern = re.compile(‘AV’)
result = pattern.findall(‘AV Analytics Vidhya AV’)
print result
result2 = pattern.findall(‘AV is largest analytics community of India’)
print result2

Результат:

[‘AV’, ‘AV’]
[‘AV’]

В примерах был приведен поиск определенной последовательности символов. А как быть, если нет определенного шаблона, а наша задача – вернуть набор символов из строки, которая отвечает определенным правилам? Чаще всего это требуется при извлечении информации из строк. Этого можно добиться, прибегнув к специальным символам. Приведем самые популярные из них:

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

Примеры использования регулярных выражений

Вернуть первое слово из строки

Прежде всего попытаемся вытащить каждый символ

result = re.findall(r’.’, ‘AV is largest Analytics community of India’)
print result

Результат:

[‘A’, ‘V’, ‘ ‘, ‘i’, ‘s’, ‘ ‘, ‘l’, ‘a’, ‘r’, ‘g’, ‘e’, ‘s’, ‘t’, ‘ ‘, ‘A’, ‘n’, ‘a’, ‘l’, ‘y’, ‘t’, ‘i’, ‘c’, ‘s’, ‘ ‘, ‘c’, ‘o’, ‘m’, ‘m’, ‘u’, ‘n’, ‘i’, ‘t’, ‘y’, ‘ ‘, ‘o’, ‘f’, ‘ ‘, ‘I’, ‘n’, ‘d’, ‘i’, ‘a’]

Чтобы в конечном результате не было пробела, применяем вместо . \w.

result = re.findall(r’\w’, ‘AV is largest Analytics community of India’)
print result

Результат:

[‘A’, ‘V’, ‘i’, ‘s’, ‘l’, ‘a’, ‘r’, ‘g’, ‘e’, ‘s’, ‘t’, ‘A’, ‘n’, ‘a’, ‘l’, ‘y’, ‘t’, ‘i’, ‘c’, ‘s’, ‘c’, ‘o’, ‘m’, ‘m’, ‘u’, ‘n’, ‘i’, ‘t’, ‘y’, ‘o’, ‘f’, ‘I’, ‘n’, ‘d’, ‘i’, ‘a’]

Сейчас достанем каждое слово (применяя + или *)

result = re.findall(r’\w*’, ‘AV is largest Analytics community of India’)
print result

Результат:

[‘AV’, », ‘is’, », ‘largest’, », ‘Analytics’, », ‘community’, », ‘of’, », ‘India’, »]

В результат снова попали пробелы, поскольку * означает «ноль или больше символов». Используя + удается решить эту проблему:

result = re.findall(r’\w+’, ‘AV is largest Analytics community of India’)
print result

Результат:

[‘AV’, ‘is’, ‘largest’, ‘Analytics’, ‘community’, ‘of’, ‘India’]

Дальше вытащим первое слово, применяя ^:

result = re.findall(r’^\w+’, ‘AV is largest Analytics community of India’)
print result

Результат:

[‘AV’]

Если мы применяем $ вместо ^, то мы получим не первое слово, а последнее:

result = re.findall(r’\w+$’, ‘AV is largest Analytics community of India’)
print result

Результат:

[‘India’]

Вернуть первые 2 символа каждого слова

Способ 1: применяя \w, вытащить два последовательных символа, за исключением пробельных, из каждого слова:

result = re.findall(r’\w\w’, ‘AV is largest Analytics community of India’)
print result

Результат:

[‘AV’, ‘is’, ‘la’, ‘rg’, ‘es’, ‘An’, ‘al’, ‘yt’, ‘ic’, ‘co’, ‘mm’, ‘un’, ‘it’, ‘of’, ‘In’, ‘di’]

Способ 2: вытащить два последовательных символа, применяя символ границы слова (\b):

result = re.findall(r’\b\w.’, ‘AV is largest Analytics community of India’)
print result

Результат:

[‘AV’, ‘is’, ‘la’, ‘An’, ‘co’, ‘of’, ‘In’]

Способ 3: вернуть список доменов из списка адресов электронного почтового адреса

Поэтапное решение задачи. Для начала нужно вернуть все символы после «@»:

result = re.findall(r’@\w+’, ‘abc.test@gmail.com, xyz@test.in, test.first@analyticsvidhya.com, first.test@rest.biz’)
print result

Результат:

[‘@gmail’, ‘@test’, ‘@analyticsvidhya’, ‘@rest’]

Части «.com», «.in» и так далее не попали в результат. Внесем изменения в код:

result = re.findall(r’@\w+.\w+’, ‘abc.test@gmail.com, xyz@test.in, test.first@analyticsvidhya.com, first.test@rest.biz’)
print result

Результат:

[‘@gmail.com’, ‘@test.in’, ‘@analyticsvidhya.com’, ‘@rest.biz’]

Альтернативный способ — вытащить домен верхнего уровня, применяя группировку — ( ):

result = re.findall(r’@\w+.(\w+)’, ‘abc.test@gmail.com, xyz@test.in, test.first@analyticsvidhya.com, first.test@rest.biz’)
print result

Результат:

[‘com’, ‘in’, ‘com’, ‘biz’]

Извлечь дату из строки

Применяем \d для извлечения цифр.

result = re.findall(r’\d{2}-\d{2}-\d{4}’, ‘Amit 34-3456 12-05-2007, XYZ 56-4532 11-11-2011, ABC 67-8945 12-01-2009’)
print result

Результат:

[’12-05-2007′, ’11-11-2011′, ’12-01-2009′]

Для извлечения только года на помощь придут скобки:

result = re.findall(r’\d{2}-\d{2}-(\d{4})’, ‘Amit 34-3456 12-05-2007, XYZ 56-4532 11-11-2011, ABC 67-8945 12-01-2009’)
print result

Результат:

[‘2007’, ‘2011’, ‘2009’]

Извлечь все слова, начинающиеся с гласной

Вначале вернем все слова:

result = re.findall(r’\w+’, ‘AV is largest Analytics community of India’)
print result

Результат:

[‘AV’, ‘is’, ‘largest’, ‘Analytics’, ‘community’, ‘of’, ‘India’]

Затем вернем только те, которые начинаются на определенные буквы, в чем поможет []:

result = re.findall(r'[aeiouAEIOU]\w+’, ‘AV is largest Analytics community of India’)
print result

Результат:

[‘AV’, ‘is’, ‘argest’, ‘Analytics’, ‘ommunity’, ‘of’, ‘India’]

В примере представлены обрезанные слова «argest» и «ommunity». Чтобы убрать их, применяем \b, чтобы обозначить границы слова:

result = re.findall(r’\b[aeiouAEIOU]\w+’, ‘AV is largest Analytics community of India’)
print result

Результат:

[‘AV’, ‘is’, ‘Analytics’, ‘of’, ‘India’]

Еще один вариант — использовать ^ внутри квадратных скобок с целью инвертирования группы:

result = re.findall(r’\b[^aeiouAEIOU]\w+’, ‘AV is largest Analytics community of India’)
print result

Результат:

[‘ is’, ‘ largest’, ‘ Analytics’, ‘ community’, ‘ of’, ‘ India’]

Видим, что в результат попали слова, которые начинаются с пробелам. Чтобы решить проблему – включите пробел в квадратные скобки.

result = re.findall(r’\b[^aeiouAEIOU ]\w+’, ‘AV is largest Analytics community of India’)
print result

Результат:

[‘largest’, ‘community’]

Проверить номер телефона (он должен начинаться с 8 или 9 с длиной в 10 знаков)

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

li = [‘9999999999’, ‘999999-999’, ‘99999×9999′]

for val in li:
if re.match(r'[8-9]{1}[0-9]{9}’, val) and len(val) == 10:
print ‘yes’
else:
print ‘no’

Результат:

yes
no
no

Разбить строку по нескольким разделителям

Пример решения:

line = ‘asdf fjdk;afed,fjek,asdf,foo’ # String has multiple delimiters («;»,»,»,» «).
result = re.split(r'[;,\s]’, line)
print result

Результат:

[‘asdf’, ‘fjdk’, ‘afed’, ‘fjek’, ‘asdf’, ‘foo’]

К тому же можно использовать метод re.sub(), чтобы заменить пробелами всех разделителей.

line = ‘asdf fjdk;afed,fjek,asdf,foo’
result = re.sub(r'[;,\s]’,’ ‘, line)
print result

Результат:

asdf fjdk afed fjek asdf foo

Извлечь данные из html-файла

Предположим, что наша задача – извлечь данные из файла .html, которые находятся между <td> и </td>, кроме 1 столбцас номером. При этом html- код находится в строке.

Пример содержимого файла:

1NoahEmma2LiamOlivia3MasonSophia4JacobIsabella5WilliamAva6EthanMia7MichaelEmily

Решение (если поместить содержимое htmlфайла в переменную test_str):

result = re.findall(r’\d([A-Z][A-Za-z]+)([A-Z][A-Za-z]+)’, test_str)
print result

Результат:

[(‘Noah’, ‘Emma’), (‘Liam’, ‘Olivia’), (‘Mason’, ‘Sophia’), (‘Jacob’, ‘Isabella’), (‘William’, ‘Ava’), (‘Ethan’, ‘Mia’), (‘Michael’, ‘Emily’)]

Выводы

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

Если у вас остались вопросы или вы столкнулись со сложностями, сообщите нам в комментариях.

2 комментария для “Как использовать регулярные выражения в Python. Примеры для новичков

  • 29.04.2021 в 01:12
    Постоянная ссылка

    Спасибо большое. Отличные примеры, которые легко воспринимаются. В инсте нам таких не давали(((

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *