Занятие 8
Регулярные выражения
Что это такое
Одиночные символы
Операторы
RegEx101 и Python
Что это такое
Регулярные выражения — это способ найти последовательность в тексте, согласно заданным правилам.
По сути, «регулярки» — это трафарет для текста.

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



Узнать больше:
  1. Регулярные выражения в Python от простого к сложному — ShashkovS, Хабр — стоит просмотреть таблички, в остальное можно особо не вчитываться.
  2. Регулярные выражения (regexp) основы — Molechka, Хабр​ — очень простой язык и комиксы​.
Виды регулярных выражений
Регулярные выражения делятся на:​
  • одиночные символы,
  • операторы,
  • операторы-квантификаторы
  • и оператор-экран.

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

Операторы совершают некое действие с одиночными символами; указывают одиночным символам, как себя вести: например, «начни с начала строки» или «выбери из диапазона».





Операторы-квантификаторы говорят: «Возьми этот символ и повтори его N раз».

Однако все операторы и сами похожи на символы. Если нам нужно найти сам символ, а не использовать знак как оператор, то мы «экранируем» его — ставим перед ним \ косую черту. Она похожа на зеркальце, в которое смотрится символ, чтобы разглядеть в себе свою истинную сущность.
Одиночные символы
Ес​ли нужно найти любой символ, мы ставим точку:
  • текст: луна
  • регулярка: .
  • питон: r.search (r'.', 'луна')[0]
  • результат: 'л'

Ес​ли нужно найти конкретный символ, мы просто пишем этот символ:
  • текст: луна
  • регулярка: на
  • питон: r.findall (r'на', 'луна')
  • результат: 'на'

Если нужно найти один из перечисленных символов, пишем нужные символы в квадратных скобках:
  • текст: Весел ли вереск в Версале?
  • регулярка: [вВ]е
  • питон: r.findall (r'[вВ]е', 'Весел ли вереск в Версале?')
  • результат: ['Ве', 'ве', 'Ве']

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

  • текст: Кабы я была царицей, I would be a Queen.
  • регулярка: [А-ЯЁA-Z]
  • питон: r.findall (r'[А-ЯЁA-Z]', 'Кабы я была царицей, I would be a Queen.')
  • результат: ['Κ', 'Ι', 'Q']

Регистр важен!





Спорные буквы и буквы с ударениями в диапазонах прописываем отдельно:
  • в русском языке нужно отдельно прописывать «ёЁ» (почему?);
  • в немецком — «ÄÖÜäöüß»;
  • в турецком — «ğüşöçİĞÜŞÖÇ»;
  • во французском — «À-ÿ»;
  • в арабском — «[ء-ي]»;
  • в китайском — «[一-龥]».

Если нужно найти любую букву, цифру или _ нижнее подчёркивание, используем \w.
  • текст: How?
  • регулярка: \w
  • питон:
  1. r.findall (r'\w', 'How?')
  2. r.search (r'\w', 'How?') [0]
  • результат:
  1. ['H', 'o', 'w', '?']
  2. 'Η'

Если нужно найти не-букву, не-цифру и не-нижнее-подчёркивание, используем \W.
  • текст: How?
  • регулярка: \W
  • питон: r.search (r'\W', 'How?') [0]
  • результат: '?'

Если нужно найти цифру, используем \d.
  • текст: В каком месяце 28 дней?
  • регулярка: \d
  • питон: r.search (r'\d', 'В каком месяце 28 дней?') [0]
  • результат: '2'

Расшифровка
  • w как word
  • d как digits
Границы
Если нужно найти любой пробельный символ, используем ​\s:
  • текст:
лягушки
квакают?

  • регулярка: \s
  • питон: r.search (r'\s', 'лягушки\nквакают?')[0]
  • результат: \n

К пробельным символам относятся:
  • сам пробел ' ';
  • табуляция \t;
  • перенос строки \n.

Если мы знаем, что нам нужно найти именно табуляцию или перенос строки, мы можем напрямую прописать это в регулярном выражении, указав \t или \n соответственно.

Если нужно найти любой непробельный символ, используем ​\S:
  • текст: \tt\t
  • регулярка: \S
  • питон: r.search (r'\t', '\tt\t')[0]
  • результат: 't'

Расшифровка
  • s как space
  • t как tabulation
  • n как new line
  • b как border, break



Если нужно найти границу слова, то есть
  • начало слова: слева пусто или не-буква,
  • конец слова: справа пусто или не-буква,
то используем \b:
  • текст: мы тут
  • регулярка: \b
  • питон: r.findall (r'\b', 'мы тут')
  • результат: [' ',' ',' ',' ']

Если нужно найти неграницу слова:
  • слева и справа буквы;
  • слева и справа не-буквы;
  • вспоминаем про «огнеупорные трубы»;​
то используем \B:
  • текст: пухля
  • регулярка: \B
  • питон: r.findall (r'\B', 'пухля')
  • результат: [' ',' ',' ',' ']

Иными словами, чистый \B считает, сколько есть границ внутри слова между буквами.

Стоит использовать вместе с другими символами и операторами, например:
  • текст: наркотики
  • регулярка: \Bкотик
  • питон: r.findall (r'\Bкотик', 'наркотик')
  • результат: [' котик']
Квантификаторы
Квантификаторы — от слова "quantity", количество — это операторы, которые позволяют нам расширить действие указанного символа и прописать, сколько раз должен повторяться подобный символ. Мы можем задать как точное число повторений, так и некий условный диапазон.

Точные диапазоны указываются в фигурных скобках:
  • {m} — ровно m повторений,
  • {m,n} — от m до n повторений включительно,
  • {m,} — не менее m повторений,
  • {,n} — не более n повторений.

Так, если нам нужно найти слова из пяти букв, нам необязательно писать \w\w\w\w\w, достаточно написать \w{5}.



Также есть квантификаторы на грани нуля и единицы. Они отображаются специальными символами — звёздочкой, плюсом, прямой чертой и вопросительным знаком.

1. * звёздочка говорит, что предыдущий символ повторяется 0 и более раз
  • жесть* найдёт и жест, и жесть, и жестььььь
2. +плюс говорит, что предыдущий символ повторяется 1 и более раз
  • жесть+ найдёт жесть и жестььььь
3. ?вопросительный знак говорит, что предыдущий символ может быть, а может и не быть — иными словами, либо 0, либо 1 раз
  • ж?есть найдёт жесть и есть​

Второе значение вопросительного знака — смягчение жадных квантификаторов. Все квантификаторы по умолчанию жадные — они захватывают так много, как только могут. Чтобы этого избежать, мы делаем квантификаторы ленивыми, подставляя к ним ?
  • жадный — .*
  • ленивый — .*?
Другие операторы
В регулярных выражениях роль играют и скобки:
1. ()
  • если есть несколько значений (группы символов и слова), разделённых вертикальной чертой |, то выбери любой из этих вариантов, не разбивая их на отдельные символы;​
  • если в скобках стоит регулярное выражение, а после него идёт квантификатор, примени квантификатор ко всему регулярному выражению.
2. [] — для одного значения выбери любой символ из тех, что в скобках (быстрее круглых скобок).

3. {} — умножь на символ в скобках.





Мы можем показать начало и конец строки:
  • ^ — начало строки,
  • $ — конец строки.

Однако в квадратных скобках тот же самый символ ^ действует иначе: он показывает, что в этом месте находится что угодно, кроме содержимого скобок. Иными словами, он отменяет действие скобок.

  • текст: речка, репка
  • регулярка: ре[^ч]ка
  • питон: re.findall (r'ре[^ч]ка'; 'речка, репка')
  • результат: ['репка']
Запомнить знак отмены ^ можно по клюву утки
RegEx101
Сайт RegEx101 позволяет увидеть, как работают ваши регулярные выражения, и протестировать их на корректность. Работает с небольшими объёмами текстов и плохо переваривает большие документы.

Алгоритм работы:

  1. Слева в поле Flavor выбираете Python.

2. По центру в поле Test String вставляете ваш текст, который нужно обработать.

3. Сверху, в поле Regular Expression, вставляете регулярное выражение.

4. Справа сверху, в поле Explanation, проверяете, верно ли вы помните, что значат указанные вами символы и операторы.



5. Справа по центру, в поле Match Information, проверяете, правильно ли определяются строки в вашем тексте.

6. Если всё верно, там же в поле Match Information нажимаете на прямоугольник со стрелкой вверх — Export Matches.

7. В этом поле выбираете нужный формат выгрузки — csv или plain text:
  • в csv указывается начальная и конечная позиция строки,​
  • в plain text указывается только найденное значение.
8. Нажимаете на знак копирования в правом верхнем углу окошка — copy to clipboard — и вставляете полученную информацию в эксель или в текстовый файл.​
Регулярное выражение для поиска Unicode эмодзи
[\U0001F600-\U0001F64F]|[\U0001F300-\U0001F5FF]|[\U0001F680-\U0001F6FF]|[\U0001F700-\U0001F77F]|[\U0001F780-\U0001F7FF]|[\U0001F800-\U0001F8FF]|[\U0001F900-\U0001F9FF]|[\U0001FA00-\U0001FA6F]|[\U0001FA70-\U0001FAFF]|[\U00002702-\U000027B0]|[\U000024C2-\U0001F251]|[\U0001F1E6-\U0001F1FF]{2}
Python
Для работы с регулярными выражениями понадобится библиотека re. Соответственно, первая строка кода в любом документе, если вы хотите работать с регулярками —
import re

Чаще всего используются функции:

1. re.match (pattern, text) — проверяет, начинается ли текст с данной комбинации.

2. re.search (pattern, text) — ищет первое подходящее значение и показывает его позицию в тексте.

3. re.split (pattern, text) — режет строку на части по указанному выражению и возвращает список значений; разница.

  • 'text'.split ('separator') — делит строку на части по одному символу или одной последовательности символов, сепаратор теряется при разбивке;
  • re.split (r'\s*[+*-]\s*', text) — регулярное выражение без подгрупп делает то же самое, что и обычный строчный сплит;
  • re.split (r'\s*([+*-])\s*', text) — символы +*-здесь заключены в круглые групповые скобки, и при разделении они будут добавлены в финальный список как отдельные элементы;
  • re.split (r'\+ | \*', text) — вертикальная черта позволяет ввести несколько сепараторов.





8. re.sub (original_pattern, needed_pattern, text) — заменяет выражения; меняющиеся места группируются, а группы либо нумеруются, либо именуются:
  • \1 \2 — числа для ссылки на номер группы,​
  • (?P<name>\d\w) — для присвоения группе конкретного буквенного имени,
  • \g<name> — для ссылки на группу в needed_pattern.

9. re.findall (pattern, text) — ищет все совпадения в тексте и создаёт из них список значений.

10. list (re.finditer (pattern, text)) — итератор, возвращающий все совпадения с их начальной и конечной позицией.

Подобно тому, как мы сообщаем питону, что если перед строкой стоит f, то фигурные скобки внутри строки — это не текст, а место для вставки переменной, точно так же мы сообщаем, что строка — не текст, а регулярное выражение, с помощью буквы r: r'\d'
Посмотреть вокруг
Если сохранить результат поиска по match, search и split в переменную, можно будет вывести:

1. peremennaya.start () — начальную позицию;

2. peremennaya.end () — конечную позицию;

3. peremennaya.group () — результат поиска;

4. peremennaya.group (n) — найденную подгруппу:

  • число соответствует уровню погружения: чем больше число, тем меньше найденный кусочек;
  • в регулярном выражении подгруппы должны быть выделены круглыми скобками ();
  • число не может быть больше, чем количество уровней погружения:
  • например, в r'12 (\w (\d\w) \d)' максимальное число 2, а 3 выдаст ошибку IndexError.



Мы можем добавить в выражение lookaround, которые буквально говорят питону «посмотри вокруг и начни действовать, отталкиваясь от внешнего контекста». В круглых скобках после открывающейся скобки:
  • ?: — позволяет не выделять в результате выражение в скобках в отдельную группу;
  • ?= — positive lookahead — посмотри вперёд и найди там это выражение, но в вывод его не включай;
  • ?!= — negative lookahead — посмотри вперёд и найди там что угодно, кроме этого выражения;
  • ?<= — positive lookbehind — посмотри назад и найди там это выражение, но в вывод его не включай;
  • ?<! — negative lookbehind — посмотри назад и найди там что угодно, кроме этого выражения.

Все эти условия, кроме ?:, можно использовать только с известным числом символов и вариантов заполнения.
✅ (?: https | ftp)
❌ (?<= https | ftp)

Узнать больше можно в официальной документации библиотеки.
Подсчёт найденных значений в длинных списках
from collections import Counter — загрузка библиотеки

Counter (list) — подсчёт по значениям без сортировки

Counter (list).most_common() — подсчёт по значениям с сортировкой результатов от большего к меньшему

This site was made on Tilda — a website builder that helps to create a website without any code
Create a website