[Перевод] Регулярные выражения: никакой магии


Автор: PatientZero
Источник: https://habrahabr.ru/post/348890/
image

Код этого поста, как и сам пост, выложен на github.

До недавнего времени регулярные выражения казались мне какой-то магией. Я никак не мог понять, как можно определить, соответствует ли строка заданному регулярному выражению. А теперь я это понял! Ниже представлена реализация простого движка регулярных выражений менее чем в 200 строках кода.

Часть 1: Парсинг


Спецификация


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

  • .: соответствие любому символу
  • |: соответствие abc или cde
  • +: соответствие одному или более предыдущего паттерна
  • *: соответствие 0 или более предыдущего паттерна
  • ( и ) для группировки

Хотя набор опций невелик, с его помощью можно создать интересные regex-ы, например, m (t|n| ) | b позволяющий найти субтитры к Star Wars без субтитров к Star Trek, или (..)* для нахождения множества всех строк чётной длины.

План атаки


Мы будем анализировать регулярные выражения в три этапа:

  1. Парсинг (синтаксический анализ) регулярного выражения в синтаксическое дерево
  2. Преобразование синтаксического дерева в конечный автомат
  3. Анализ конечного автомата для нашей строки

Для анализа регулярных выражений (подробнее об этом ниже) мы будем использовать конечный автомат под названием NFA. На высоком уровне NFA будет представлять наш regex. При получении входных данных мы будем перемещаться в NFA от состояния к состоянию. Если мы придём в точку, из которой невозможно совершить допустимого перехода, то регулярное выражение не соответствует строке.
Читать дальше →

Комментарии 0


Чтобы читать и оставлять комментарии вам необходимо зарегистрироваться и авторизоваться на сайте.

Моя страницаНастройкиВыход
Отмена Подтверждаю
100%
Отмена Подтверждаю
Отмена Подтверждаю