Рубріки: Теория

Что такое Python RegEx: регулярные выражения в языке Python

Роман Гармидер

Регулярные выражения (Regular expressions) или RegEx – это последовательности символов, задающие шаблоны для поиска или замены нужного фрагмента текста в строке или файле. Попросту говоря, это своего рода крошечный язык программирования, предоставляющий множество инструментов для поиска, замены и извлечения определенных фрагментов текста. К примеру, с его помощью можно быстро найти в тексте адреса электронной почты или телефонные номера. Регулярные выражения поддерживаются большинством современных языков программирования, в которых представлены различные по удобству и функционалу средства. В этой статье мы расскажем о самых основных особенностях применения RegEx в языке Python. А так же про то, как заменить часть текста в строке (спойлер: это не replace, для этого нужен re.sub() )

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

Символ

Описание

Пример

[]

любой одиночный символ в заданном диапазоне

“[a-z]”

\

указывает на специальную последовательность (может также использоваться для экранирования спецсимволов)

“\ d”

.

любой символ, кроме символа новой строки

“he..o”

^

сравнение начинается с начала строки

“^hello”

$

сравнение начинается с конца строки

“world$”

*

ноль или больше символов

“aix*”

+

один или больше символов

“aix+”

{}

точно указанное количество вхождений

“al {2}”

|

либо одно, либо другое

“falls|stays”

()

охват и группировка

 

Взглянем на основные флаги и шаблоны регулярных выражений:

\w

любой буквенный и цифровой символ, а также нижнее подчеркивание

\W

любой небуквенный и нецифровой символ и не нижнее подчеркивание

\d

любая цифра

\D

любой символ, кроме цифры

\s

любой пробельный символ (пробел, табуляция, конец строки и т. п.)

\S

любой непробельный символ

\b

Начало или конец слова (слева пусто или не-буква, справа буква и наоборот). Соответствует позиции, а не символу.

\B

Не граница слова: либо и слева, и справа буквы, либо и слева, и справа НЕ буквы.

[abc]

любой символ из приведенного подмножества

[^abc]

любой символ, кроме перечисленных

[a-z]

любой символ в диапазоне от a до z

[0-9]

любой символ в диапазоне от 0 до 9

Модуль re

Для работы с регулярными выражениями в Python предусмотрен специальный модуль re. Прежде чем начать работу его нужно импортировать:

import re

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

  •         Если речь идет об одноразовой проверке, достаточно использовать функции модуля re. В таком случае произойдет компиляция регулярного выражения и поиск соответствий.
  •         Если проверка будет осуществляется многократно, предпочтительней будет сперва один раз скомпилировать выражение (получив доступ к специальному объекту класса re.regex), после чего использовать его методы.

Обычно код регулярных выражений записывается с префиксом r, подавляющих экранирование. Экранирование нужно обозначения специальных флагов, которые мы рассматривали выше, таких как \w . Например, во избежание необходимости дублировать экранирующий символ при поиске переноса строки, лучше указать r”\n” вместо “\\n”.

Функции RegEx

В модуле re определены несколько функций и констант для работы с RegEx. Вот наиболее распространенные функции:

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

С помощью примеров разберем, как работают эти функции и в чем их особенности.

re.search(pattern, string)

Функция re.search() используется для поиска в строке первого вхождения заданного шаблона. Ниже приведен шаблон для поиска в тексте e-mail адреса:

s = "His email is john_w@gmail.com"
match = re.search(r'[\w.-]+@[\w.-]+', s)
if match:
    print(match.group())
else:
    print("соответствия не найдено")

В случае успеха функция возвращает объект match, а с помощью метода group() можно извлечь найденный текст.

re.findall(pattern, string)

Если нам нужно найти все вхождения, следует использовать функцию re.findall(). В случае успеха она возвращает список, который содержит все искомые вхождения по порядку. В противном случае функция возвратит пустой список.

s = "Her phone numbers: 12542-78514 and 96753-82514"
match = re.findall(r'\d{5}', s)
if match:
    print(match)

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

re.match(pattern, string)

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

ее работы со строкой “First Second Third” и шаблоном “First” окажется положительным. Однако, если мы попытаемся найти фрагмент “Second”, соответствий не обнаружится.

result = re.match(r'First', 'First Second Third')
# OK
result = re.match(r'Second', 'First Second Third')
# None

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

Функция re.split() разделяет строку по заданному шаблону. Например, разобьем строку на отдельные слова, разделенные пробелом:

txt = "Split at each white-space character"

x = re.split("\s", txt)

print(x)

# ‘Split’ ‘at’ ‘each’ ‘white-space’ ‘character’

Кроме того, эта функция принимает аргумент maxsplit со значением, по умолчанию равным 0. В вышеприведенном примере она разделит строку на максимальное количество частей. Если же специально задать этот аргумент, то разделение будет осуществлено не более заданного количества раз.

x = re.split("\s", txt, maxsplit=1)

В этом случае строка будет разделена всего на две части.

re.sub(pattern, repl, string, count=0)

Функция re.sub() осуществляет поиск шаблона в строке, заменяя его указанной подстрокой. В случае отсутствия шаблона никаких изменений не происходит. Следует упомянуть, что для операций поиска и замены пользователи часто пытаются использовать функцию replace, которой попросту не существует. Для этих целей предназначена re.sub(). Вот пример ее использования:

result = re.sub(r'small', 'big', 'Our company is small')

print result

# 'Our company is big'

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

string = 'abc 12\
de 23 \n f45 6'
pattern = '\s+'
replace = ''
new_string = re.sub(r'\s+', replace, string, 1)
print(new_string)
# ‘abc12de 23’
# ‘f45 6’

re.compile(pattern, repl, string)

С помощью функции re.compile() можно собрать регулярное выражение в отдельный объект, который в дальнейшем будет использоваться как шаблон для поиска, а также избавит от неоднократного переписывания одного и того же выражения.

pattern = re.compile('the')
result = pattern.findall('We are the biggest company in the world')
print result
result2 = pattern.findall('We are the best company')
print result2
# ‘the’, ‘the’
# ‘the’

Кратко коснемся понятия флагов в регулярных выражениях. Многие функции в RegЕx принимают необязательный аргумент, известный как flag. Флаги влияют на некоторые особенности работы регулярных выражений. Они доступны в модуле re под двумя именами: длинным, например, IGNORECASE, и его коротким, однобуквенным сокращением, таким как I.

Флаг (полная и краткая формы) Значение
ASCII, A По умолчанию шаблонам \w, \W, \b, \B, \d, \D, \s, \S соответствуют все соответствующие символы Юникода. Установка флага ускоряет работу, если все соответствия лежат внутри ASCII. Здесь же можно упомянуть флаг UNICODE (U), который используется для проверки обратной совместимости.
DOTALL, S По умолчанию символ \n конца строки не подходит под точку. С этим флагом точка – любой символ вообще.
IGNORECASE, I Сравнение не будет зависеть от регистра символов. В некоторых случаях флаг полезен, хотя и замедляет выполнение программы.
MULTILINE, M Специальные символы ^ и $ соответствуют началу и концу каждой строки.
VERBOSE, X Если ваши регулярные выражения не очень читабельные, то этот флаг – именно то, что вам нужно. Он позволяет зрительно разделять логические части регулярных выражений и даже добавлять комментарии (рассматривает неэкранированный # как маркер комментария). Флаг игнорирует пробелы (за исключением их наличия внутри множества [] или случаев, когда классу символа или пробелу предшествует обратная косая черта).

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

P.S. Для быстрой проверки регулярных выражений рекомендую очень удобный ресурс: https://regex101.com.

 

Останні статті

Что такое прокси-сервер: пояснение простыми словами, зачем нужны прокси

Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…

21.11.2024

Что такое PWA приложение? Зачем необходимо прогрессивное веб-приложение

Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…

19.11.2024

Как создать игру на телефоне: программирование с помощью конструктора

Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…

17.11.2024

Google Bard: эффективный аналог ChatGPT

В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…

14.11.2024

Скрипт и программирование: что это такое простыми словами

Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…

12.11.2024

Дедлайн в разработке: что это такое простыми словами

Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…

11.11.2024