Продолжим говорить о регулярных выражениях в Python в рамках NLP. Регулярные выражения нужны для поиска подстрок, которые удовлетворяют правилам. Например, нужно найти все слова, которые начинаются с заглавной буквы «А», или все даты в предложении, которое содержит и другие виды чисел. Сегодня мы расскажем об основных символах, которые образуют регулярные выражения: замена, группировка, перечисление символов, а также специальные символы в Python.
Один любой символ или повторять до бесконечности
Когда появляется ситуация, когда мы не знаем какой именно символ используется, то используется точка .
. А когда нужно повторить какой символ сколько-то раз, то используется звездочка *
(0 или n символов) или плюс +
(1 или n символов). Рассмотрите примеры регулярных выражений в Python:
# aa.bb. # Может значить aapbby или aa4bb$ # a.b* # Может значить acbbb или aqb или a,bbbbbb >>> import re >>> re.search('aa.bb.', 'aapbby') <re.Match object; span=(0, 6), match='aapbby'> >>> re.search('a.b*', 'a,bbbbbb') <re.Match object; span=(0, 8), match='a,bbbbbb'>
Точка и звездочка могут использоваться вместе .*
, тогда это значит любой символ повторяется сколько-то раз. Это удобно, когда вы не помните все выражение, но знаете каким символом он заканчивается. Ниже пример того, как применять такое регулярное выражение в Python.
>>> re.search('<h.*>', '<html>') <re.Match object; span=(0, 6), match='<html>'>
Но стоит быть очень осторожным с ним, поскольку это регулярное выражение будет смотреть совпадения до конца строки. А это бывает не то, что нужно:
# Вместо <html> совпала вся строка, потому что она оканичается на символ '>' >>> re.search('<h.*>', '<html>..<li>...</li>') <re.Match object; span=(0, 20), match='<html>..<li>...</li>'>
Группа символов
Символы могут быть сгруппированы с помощью круглых скобок. К этим группам могут быть применены повторения *
или +
. Кроме того внутри скобок может использоваться оператор ИЛИ в виде |
. Следующие примеры показывают разные регулярные выражения в Python с применением группировок:
# (ac)* # соответсвует acacac или acac # Знак | соответсвует ИЛИ: >>> re.search('d(e|i)n', 'den') <re.Match object; span=(0, 3), match='den'> >>> re.search('d(e|i)n', 'din') <re.Match object; span=(0, 3), match='din'>
Перечисление символов
Как мы увидели, использовать .*
опасно. Поэтому лучше всего перечислять всевозможные символы внутри квадратных скобок []
. Например, не известно какой знак препинания следует дальше, тогда в Python можно регулярное выражение вывести следующим образом:
>>> pattern = 'a[,u]bc' >>> re.search(pattern, 'a,bc') <re.Match object; span=(0, 4), match='a,bc'> >>> re.search(pattern, 'aubc') <re.Match object; span=(0, 4), match='aubc'> >>> re.search(pattern, 'adbc') # Ничего не нашел
Последний пример не соответствует правилу, потому что символ 'd'
не указан в []
. Также в квадратных скобках можно указывать диапазоны букв и цифры. Например, [a-z]
означает все строчные буквы английского алфавита, [A-Z]
— все прописные, а [0-9]
— все цифры. Ниже приведены примеры регулярных выражения с применением диапазонов на Python.
>>> re.search('[a-z0-5]+', 'asaBR') <re.Match object; span=(0, 3), match='asa'> >>> re.search('[a-z0-5]+', 'B612') <re.Match object; span=(2, 4), match='12'>
Также если внутри квадратных скобок указан символ ^
, то это значит «всё, что НЕ совпадает». Например, [^0-9]
— любой символ не цифра. Диапазоны кириллических символов задаются в виде [А-Яа-я]
.
Обратный слэш для пропуска символов
Как в квадратных скобках для регулярного выражения указать знак препинания точку? Ведь точка является специальным правилом, которое обозначает «любой символ». Для таких случаев используется обратный слэш \
. При использовании перед специальными символами Python интерпретирует их как обычные символы. Поэтому чтобы пропустить также сами квадратные скобки, то и перед ними тоже нужно его поставить. Ниже показаны примеры регулярных выражения с использованием обратного слэша на Python.
>>> pattern = 'a[,\.\]]bc' # Это , или . или ] >>> re.search(pattern, r'a]bc') <re.Match object; span=(0, 4), match='a]bc'> >>> re.search(pattern, r'a.bc') <re.Match object; span=(0, 4), match='a.bc'>
В строке обратный слэш тоже имеет особое значение. Он ответственен за специальные символы: \n
(новая строка), \
t
(отступ), \s
(пробел) и т.д. Их так же можно перечислять в квадратных скобках. А вот для пропуска самого обратного слэша в Python, требуется повторить его 4 раза. Ведь два слэша значат слэш как обычный символ, а чтобы пропустить его нужно два обычных. Иными словами, это:
>>> re.search('\\\\', 'ab\cd') <re.Match object; span=(2, 3), match='\\'>
интерпретируется как это:
regex("\\" [пропущенный слэш] пропускает "\\" [пропущенный слэш])
В Python строку можно инициализировать как raw (сырую), т.е. в ней обратный слэш будет считаться как обычный символ. Для этого перед строкой указывается r
. Взгляните как прописываются пути Windows в Python в виде обычной и сырой строки:
>>> 'C:\User\admin\python' File "<stdin>", line 1 'C:\User\admin\python' SyntaxError: (unicode error) 'unicodeescape' codec can t decode bytes in position 2-3: truncated \UXXXXXXXX escape SyntaxError: invalid syntax # Ошибка, потому что Python не понимает \U # Чтобы прописать путь, используется \\ или r: >>> path = 'C:\\User\\admin\\python' >>> raw_path = r'C:\\User\\admin\\python'
Цифры, пробелы, отступы
Использование обратного слэша вместе с некоторыми символами даст новое значение строке. Так, \n
— новая строка, \t
— отступ . Есть ещё полезные специальные символы:
- \d — любая цифра, эквивалентно использованию
[0-9]
- \D — любая не цифра, эквивалентно использованию
[^0-9]
- \s — пробел
- \s — не пробел
- \w — любой цифробуквенный символ, эквивалентно использованию
[a-zA-Z0-9_]
- \W — любой не цифробуквенный символ, эквивалентно использованию
[^a-zA-Z0-9_]
>>> re.search('\d\d\d\d-\d\d-\d\d', '2020-05-10') <re.Match object; span=(0, 10), match='2020-05-10'>
Этот пример на Python показывает, как можно найти даты в предложении с применением специальных символов. Ниже таблица, в который приведены символы для регулярных выражений.
Символ | Значение | Пример | Совпадения |
. | Любой одиночный символ (включая числа, пробелы и т. д.). | f.t | fat, fit, fet |
* | Повторение 0 или более раз | a*b* | aabbb, bbb, ab, aaa |
+ | Повторение 1 или более раз | a+b+ | aabbb, ab, aaabbb |
[] | Выбор любого символа в скобках | [a-z]* | apes, banana, flu |
[^] | Любой символ, которого нет в скобках | [^a-z]* | APES,FLU, BANANA |
() | Группа символов | (a*b)* | aaabaab, abaaab, bab |
| | Оператор ИЛИ внутри группы символов | b(a|i|e)d | bad, bid, bed |
\ | Знак пропуска | \.\|\\ | .|\ |
{m,n} | Повторение указанного количества раз от m до n (включительно) | a{2,3}b{2,3} | aabbb, aaabbb,aabb |
^ | Указывает, что символ или часть выражения находится в начале строки | ^a | apple, asdf, a |
$ | Сканировать до конца строки | [A-Z]*[a-z]*$ | ABCabc, zzzyx, Bob |
О том, как применять регулярные выражения в Python для решения реальных Data Science задач, вы узнаете на нашем специализированном курсе «PNLP: NLP – обработка естественного языка с Python» в лицензированном учебном центре обучения и повышения квалификации Data Scientist’ов и IT-специалистов в Москве.