NLP-01: Демистификация регулярных выражений

Один из самых недооцененных навыков, которым должен обладать любой специалист по работе с данными при работе со строками.

RegEx — один из самых мощных навыков работы с текстом; однако учиться одинаково неприятно. Мы сталкиваемся с приложениями RegEx, некоторые из его заметных применений включают подсветку синтаксиса в IDE и маршрутизацию в веб-приложениях, среди прочего и т. д. Он также заметен в областях, которые включают обработку огромных блоков данных, таких как проверка данных, веб-скрейпинг. , интеллектуальный анализ данных и т. д.

Однако в равной степени разочаровывает понимание этого, когда мы пытаемся изучить его академически. Удобнее, когда мы изучаем это на примере. Однако пример должен быть простым, но достаточно универсальным, чтобы охватить различные функции и возможности, предлагаемые Regex. После долгих размышлений я понял, что такой простой пример, как сегодняшняя дата, может охватить большинство концепций RegEx, которые я использую в своих проектах. (Ну… я искал пример, глядя на свой телефон, но, думаю, это считается попыткой.)

Итак, в этой статье мы рассмотрим различные операторы регулярных выражений, пытаясь сопоставить их в это воскресенье, 23 июля 2023 года.

Прямой поиск

Один из самых простых способов поиска строки — прямой поиск строки. На практике это можно сделать re.search('23 July 2023'). Однако не все языки программирования используют такую ​​нотацию. Например, в javascript мы представляем шаблоны регулярных выражений, используя литералы или символ косой черты /. Именно так паттерны обычно и представлены в литературе. Следовательно, для единообразия мы будем использовать запись с косой чертой на протяжении всей статьи. Теперь при прямом поиске мы представляем ее как /23 July 2023/.

Непосредственный поиск /23 July 2023/ возвращает все совпадения с датой именно в этом формате. Однако, как упоминалось ранее, даты, как правило, имеют бесчисленное множество вариаций. Одна и та же дата может быть записана как 23 jul 2023 ;23 july 2023 ;23/07/2023 или даже 23/07/23. Как мы можем адаптировать наш поиск, чтобы включить все эти различные форматы дат?

Увеличение масштабов поиска

Теперь область поиска в нашем примере должна быть уже. Однако эти широкие примеры можно свести к двум представлениям. Представление слов 23 July 2023 и числовое представление 23/07/2023. Этим двум разным строкам могут соответствовать два разных выражения. Во-первых, попробуем получить выражение, соответствующее этим двум представлениям.

Оператор дизъюнкции (|):

Нам нужно указать, где шаблон может быть изменен, чтобы включить эти различные текстовые форматы. Давайте сначала укажем разницу между двумя вариантами, 23 July 2023 и 23/07/2023. Это можно указать с помощью оператора дизъюнкции|.

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

/23 July 2023|23/07/2023/

Увидев это, вы можете подумать: «Подождите! Что-то не так с предыдущим обозначением! / используется несколько раз в строке. Разве представление не сбивает с толку? Если вы так думали, то вы правы. Это не то, как специальные символы / представлены в Regex. Эти специальные символы включают в себя. *,$, ^, +,(,), {, }, [, ] and ., среди многих других вещей, которые будут представлены позже.

Обычно мы добавляем их в выражение, используя escape-символ, который обычно представляет собой обратную косую черту (\). Следовательно, правильное выражение меняется на

/23 July 2023|23\/07\/2023/

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

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

«[ ]»:

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

Начнем с простых вещей; люди могут писать July без заглавной J или использовать дефис (-) или точку (.) вместо косой черты. Теперь, как мы можем сделать эти соображения в шаблоне? Мы не можем просто сложить все эти представления с помощью оператора дизъюнкции. (Это занимает слишком много времени при поиске сложных шаблонов; честно говоря, это просто много работы.).

Вот когда [] вступает в игру. Этот оператор рассматривает любые символы или выражения в нем как последовательность OR вероятностей. Например, когда мы упоминаем /[ab]c/, система ищет либо ac, либо bc. Нам полезно упомянуть об этих различных формах репрезентации. Следовательно, наше новое выражение сводится к

/23 [Jj]uly 2023|23[-\/\.]07[-\/\.]2023/

Обратите внимание, что мы представили период ( . ) как \.. Поскольку это один из упомянутых ранее специальных символов.

Сейчас это представление считает 23 July 2023, 23 july 2023, 23/07/2023, 23-07-2023, 23.07.2023. Теперь вы можете сделать шаг назад и расслабиться, прежде чем продолжить путешествие.

Необязательные символы

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

Оператор ?

В нашем случае следующее простейшее представление — это то, где мы представляем July без y. 23 Jul 2023 также является допустимым способом написания даты. Следовательно, нам нужно добавить это и к нашим представлениям. Итак, как мы это делаем?

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

/23 [Jj]uly? 2023|23[-\/\.]07[-\/\.]2023/

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

Скобка

Следующим простейшим представлением, которое можно добавить, является необязательное вхождение 20 в 2023. Итак, как мы это делаем? Ставим ли мы два вопросительных знака после 2 и 0? Это можно сделать для таких простых вещей. Однако что бы вы сделали с несколькими наборами символов, которые могут не встречаться, например, с множественными числами, такими как щенок и щенки? Добавляете ли вы ? после всех необязательных символов, таких как puppy?i?e?s? Это увеличивает шансы включения таких вещей, как puppet или иногда слов с ошибками, таких как puppi. Использование дизъюнкции также недопустимо, так как puppy|ies представляет puppy или ies, а не puppy или puppies.

Упростим эту задачу. Что нам нужно, так это возможность группировать разных персонажей в один блок. (Это также может помочь объединить наше текущее выражение!). Вот что дает нам оператор скобок. Мы можем сгруппировать несколько символов в блок, поместив их в круглые скобки. Следовательно, (20)?23 может соответствовать либо 2023, либо 23. Это меняет наше выражение на

/23 [Jj]uly? (20)?23|23[-\/\.]07[-\/\.](20)23/

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

/23( [Jj]uly? |[-\/\.]07[-\/\.])(20)?23/

Обратите внимание, что в нашем сокращенном выражении вокруг скобки нет пробела, а вместо текста июль. Если мы сохраним пробелы за скобками, наш шаблон станет примерно таким: 23 /07/ 2023 вместо 23/07/2023.

Это не конец, так как мы не рассматривали такие варианты, как 23-Jul-2023 или 23-Jul-23. Тем не менее, с пониманием, которое вы получили до сих пор, я призываю вас настроить существующий шаблон регулярных выражений, чтобы приспособить эти формы. Попробуйте, прежде чем продолжить статью.

Указание положения

Теперь, когда у нас есть выражение, соответствующее датам, пришло время сделать следующий шаг. Однако важно отметить, что выражение из приведенного выше шаблона включает несколько элементов, которые нам не нужны. Некоторые из них включают ситуации, когда мы можем столкнуться с несколькими случаями, когда 23 может принадлежать другому утверждению, а July 23 или July 2023. Следовательно, важно включить информацию о позиции в наше выражение.

Как добавить эту информацию?

В RegEx мы используем несколько определенных обозначений, называемых якорями позиции, для обозначения этой позиции. Некоторые из распространенных включают ^,\b,\B,$. Каждый из них имеет конкретный вариант использования, который указан в таблице ниже.

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

/\b23[ \.\/-]([Jj]uly?|07)[ \.\/-](20)?23\b/

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

Проблема в нашей выкройке!

Давайте углубимся в общую проблему, с которой мы можем столкнуться с нашим шаблоном. Предположим, вы пытаетесь запустить приведенный выше шаблон с помощью функции Python re.findall(), используя последовательность, такую ​​​​как «Сегодня 23 июля 2023 года». Вот что происходит::

Ну что мы здесь видим? Мы видим, что упомянутый нами шаблон возвращает только результаты выражений в скобках. Почему это?

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

Однако эти вещи также мешают, когда круглые скобки используются для обычного поиска по шаблону. Следовательно, нам нужно только указать системе, что эти вещи не предназначены для хранения. Как мы можем это сделать? Добавляем ?: начало выражения в скобках. Такие группы называются группами без захвата. Таким образом, наш шаблон немного меняется,

/\b23[ \.\/-](?:[Jj]uly?|07)[ \.\/-](?:20)?23\b/

Это дает нам нужный результат. Вы можете проверить вывод, который мы получаем сейчас,

Исправлен вывод шаблона. Изображение, полученное Автором.

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

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

Спасибо, что дочитали до конца эту статью. Хотя регулярные выражения — сухая тема, они очень важны во многих приложениях. Эти приложения включают интеллектуальный анализ данных, поисковые системы, веб-скрейпинг и т. Д. Я изучил Regex, когда выполнял проект анализа данных с использованием панд. С тех пор я столкнулся с несколькими случаями, когда мне приходилось использовать эти выражения. Следовательно, нужно получить базовое представление о регулярных выражениях.

Надеюсь, вам понравилось читать эту статью. Я также размещаю соответствующую информацию в Instagram или LinkedIn, чтобы вы могли следить за нами там. Или вы можете зарегистрироваться на этом сайте, чтобы получать почту всякий раз, когда я публикую статью!

ПИСАТЕЛЬ на MLearning.ai // Управление AI-видео 🗿/imagine AI 3D Models