Все о регулярных выражениях

regular-vyrazh

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

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

Чтобы увидеть, прочувствовать и изучить «регулярки», давайте поймем, зачем их вообще использовать.

Представьте, у вас есть цифровая копия романа Льва Николаевича, «Война и мир», и вам на работе поручено вычленить все русские слова, состоящие из 6 букв, где 2 и 3 буквы это «р» и «е» соответственно, то есть у нас есть шаблон *ре***, прямо как в кроссворде. Использовать обычный поиск в текстовом редакторе для нахождения нужных слов будет не правильно, ведь «ре» может встретиться в слове и не на этом месте, например, в конце. Тут на помощь нам и приходят регулярные выражения, которые решают эту задачу довольно просто — \s[А-Яа-я]ре[А-Яа-я]{3}\W

Перед тем как разобрать приведенное мной выражение, давайте рассмотрим еще один пример. Представьте, что вы работаете в телефонной компании, вам отослали базу телефонных номеров ваших клиентов, и вам надо найти и обзвонить все номера, начинающиеся с 916, при этом первая цифра +7 или 8 учитываться не должна. Для удобства каждый номер телефона расположен на отдельной строке, а других лишних данных нет. Тогда решение будет весьма простым – 916\d{7}$

Что же, а теперь давайте разбираться, как с этим работать. Лучшим способом для освоения регулярок я считаю сайт regex101.com, на нем вы сразу можете пробовать свои варианты решения поставленных задач, вставив в тестовое поле нужный текст.

Как вы заметили, чтобы мне найти нужную часть текста, достаточно просто ее написать, пока ничего сложного. Затем я использовал такую конструкцию [А-Яа-я] Она означает, что на этом месте должен быть только один символ, и этот символ может быть от «а» до «я» в двух регистрах (верхнем и нижнем). Стоит отметить, что буква «ё» должна писаться отдельно, после всех перечислений, при этом пробелы ставить не нужно — [А-Яа-яёЁ], я опустил случай с «ё» в решении задачи. Конструкция из фигурных скобок показывает, сколько раз нужно повторить выражение перед этими скобками. То есть [А-Яа-я]{3} означает, что найти надо ровно 3 буквы, подходящие под весь русский алфавит кроме «ё» и «Ё». Также в скобках можно ставить промежуток, например {3, 5}, это значит, что найдутся слова от 3 до 5 символов в длину, подходящих правилу перед скобками. Иногда вы можете увидеть и круглые скобки, они используются для двух целей: обособить некоторую часть выражений (как в примерах начальных классов), а также использовать логику ИЛИ – (x | 7) выдаст весь текст, где есть x или 7. В простых выражениях такое не используется, удобней написать [x7], но в регулярках средней сложности и выше вы можете увидеть огромные конструкции, разделенные знаком ИЛИ.

Знак ^ означает начало строки и ставится только в начале регулярного выражения, а знак $ означает конец строки, и ставится в конце. Они используются не так часто, однако их применение позволяет ставить границы слов, что облегчает работу по поиску конкретных слов без лишних приставок, суффиксов и окончаний. Пример: возьмем ту же базу с номерами телефонов. В базе номера начинаются с +7, 7 или 8, и нам поручили удалить номера с 7 в начале. Чтобы такие номера найти, достаточно написать ^7

Существует много конструкций вида \x, но я расскажу о самых полезных. \d означает любую цифру, а \s означает знак пробела. \w означает любую цифру или букву, а \W означает не цифра и не буква: пробел, знаки препинания, особые знаки.

Теперь основа регулярных выражений – символы множеств. В предыдущих примерах я их вообще не использовал, поэтому рассмотрим еще одну ситуацию. У нас есть база логинов одного форума, и вам надо написать всем пользователям с псевдонимами, которые начинаются и заканчиваются на 2, где между двойками есть хоть какие-то символы. База данных также представляет собой файл, в котором на каждый псевдоним выделена строка. Тогда решением является ^2.+2$

Первый символ множества «.». Он означает вообще любой символ, без ограничений. Символ «+» означает «от 1 до бесконечности» символов перед знаком «+». Знак «*» означает «от 0 до бесконечности» символов перед этим знаком, что в данном примере нам бы не подошло, так как мог попасться псевдоним «22», который не подошел бы нам по условию. Знак «?» означает «от 0 до 1», то есть символа перед «?» может и не быть в тексте, и найдется результат без этого символа, но удовлетворяющего остальным условиям.

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

Также регулярные выражения используются для проверки правильности написания почты во время регистрации. На этом сайте вы можете ознакомиться с вариантами проверки почты на разных языках программирования. Они рассматривают не только обычные почты (gmail, protonmail, mail.ru, yandex.ru), но и совсем неизвестные, например, созданные на своем сервере.

Практическое использование.

Когда я приводил примеры использования, я не говорил, где исполняются регулярные выражения, через специальный сайт это делать неудобно и медленно. Для решения подобных задач я использую либо оболочку командной строки linux под названием bash, либо язык программирования python, рассмотрим второй вариант, как наиболее удобный. Далее будет приведен код и его подробное описание, данный шаблон вы можете использовать в дальнейшем для своих нужд.

import re

data = open(‘phones.txt’, ‘r’).read()

found = re.findall(r’916\d{7}$’, data)

with open(‘result.txt’, ‘a’) as result:

    for element in result:

        result.write(f'{element}\n’)

Не пугайтесь, сейчас все объясню.

import re – здесь мы добавляем модуль для работы с регулярными выражениями под названием «re».

data = open(‘phones.txt’, ‘r’).read() – здесь мы записываем в переменную «data» (название может быть любое) весь текст из нашей базы данных «phones.txt», «r» означает режим чтения, то есть случайно изменить файл вы не сможете, функция «read()» выгружает весь текст в оперативную память, чтобы компьютер мог быстро с ней работать. Если ваш текстовый файл находится не в одной папке с программой, тогда надо указывать полный путь файла, начиная с имени диска (C:\\Users…).

found = re.findall(‘916\d{7}$’, data) – здесь переменной «found» (название может быть любое) присваиваются все найденные значения, подходящие регулярному выражению в кавычках. «Findall» это функция модуля «re», которая выдает все значения, прошедшие правила регулярного выражения. «data» — это переменная, в которую мы вложили текст, т.е. правило регулярного выражения применяется к тексту «phones.txt».

with open(‘result.txt’, ‘a’) as result: — здесь мы создаем новый текстовый файл для записи в него результатов поиска под названием «result.txt.», этот файл будет создан в той же папке, что и программа. «а» означает, что если файла с таким именем нет, то он создастся, а если есть, то в такой файл запишется после всего текста наш результат.

    for element in result:

        result.write(f'{element}\n’) – здесь мы создаем цикл, который проходит по всем результатам поиска и записывает каждый результат на отдельной строке. Если вы хотите результаты в строчку, то замените \n на пробел.

Данную программу я советую запускать в среде разработки для python (python idle, pycharm, anaconda и пр.)

Заменяя исходное регулярное выражение, а также входной и выходной файлы своими данными, вы можете фильтровать текст, и, в отличие от подобной функции, встроенной в текстовые редакторы (EditPad и пр.) результаты вписываются в отдельный файл, что очень удобно. Если вам это по душе, то практикуйтесь, удачи!

close

Подпишитесь

Подпишитесь на рассылку, чтобы получать свежие статьи в числе первых!

Мы не спамим! Прочтите нашу политику конфиденциальности, чтобы узнать больше.

Оставить комментарий

Ваша почта не будет опубликована