Создание Regex Composer - PullRequest
       0

Создание Regex Composer

23 голосов
/ 06 сентября 2010

Я читал идею проекта Java , описанную здесь :

Пользователь приводит примеры того, что он хочет и не хочет соответствовать.Программа пытается вывести регулярное выражение, которое соответствует примерам.Затем он генерирует примеры, которые подходят и не подходят.Пользователь исправляет ошибочные примеры и составляет новое регулярное выражение.Итеративно, вы получаете регулярное выражение, достаточно близкое к тому, что вам нужно.

Это звучит как очень интересная идея для меня.У кого-нибудь есть идеи как это сделать?Моей первой идеей было что-то вроде генетического алгоритма, но мне бы очень хотелось, чтобы вы, ребята, внесли свой вклад.

Ответы [ 6 ]

4 голосов
/ 17 сентября 2010

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

Регулярные выражения эквивалентны DFA (Детерминированные конечные автоматы). Стратегия в основном всегда одна и та же:

Посмотрите на Alergia (для теории) и алгоритм MDI (для реального использования), если генерации детерминированного автомата достаточно.

Алгоритм аллергии и MDI описаны здесь: http://www.info.ucl.ac.be/~pdupont/pdupont/pdf/icml2k.pdf

Если вы хотите создавать меньшие модели, вы можете использовать другой алгоритм. Статья, описывающая это здесь: http://www.grappa.univ -lille3.fr / ~ ЛеМэй / це / TCS02.ps.gz

Его домашняя страница здесь: http://www.grappa.univ -lille3.fr / ~ ЛеМэй

Если вы хотите использовать отрицательный пример, я предлагаю вам использовать простое правило (раскраска), которое предотвращает слияние двух состояний DFA.

Если вы спросите этих людей, я уверен, что они поделятся своим источником кода.

Я сделал такой же алгоритм во время моей кандидатской диссертации. для вероятностных автоматов. Это означает, что вы можете связать вероятность с каждой строкой, и я создал программу на C ++, которая «изучает» взвешенные автоматы.

В основном эти алгоритмы работают так:

из положительных примеров: {abb, aba, abbb}

создайте простейший DFA, который принимает все эти примеры:

-> x -- a --> (y) -- b --> (z)
          \
            b --> t -- b --> (v)

x не могу указать y, прочитав, например, букву «а». Состояния x, y, z, t и v. (Z) означает, что это конечное состояние.

затем «объединить» состояния DFA: (здесь, например, результат после объединения состояний y и t.

               _
              /  \
             v    | a,b     ( <- this is a loop :-) )
x -- a -> (y,t) _/

новое состояние (y, t) - это состояние терминала, полученное путем слияния y и t. И вы можете прочитать письмо а и б из него. Теперь DFA может принимать: a (a | b) *, и регулярное выражение легко построить из DFA.

Какие состояния для слияния - это выбор, который делает основное различие между алгоритмами.

4 голосов
/ 16 сентября 2010

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

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

Первый проход: Хотите сопоставить Cat, Catches cans Результат: / Cat | Catches | Cans /

Второй проход: Искать похожие начальные условия: Результат: / Ca (t | tches | ans) /

Второй проход: поиск похожих конечных условий: Результат: / Ca (t | tch | an) s * /

Третий проход: поиск дополнительных уточнений, например повторений и отрицательных условий

1 голос
/ 01 мая 2015

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

Генетическое программирование (GP) - это метод эволюционного машинного обучения, в котором кандидат является подходящим решением дляданная проблема представляется в виде абстрактного синтаксического дерева.

Было опубликовано несколько исследований о том, как использовать GP для нахождения регулярного выражения, соответствующего данному набору примеров.Вы можете найти статьи и подробности здесь

Веб-приложение, которое делает это, размещено на regex.inginf.units.it .Исходный код приложения был опубликован на github

1 голос
/ 16 сентября 2010

Программа пытается вывести регулярное выражение, соответствующее примерам

Не думаю, что это полезный вопрос.Вы должны семантически знать, что вам нужно изобразить, чтобы сделать вывод.Когда вы пишете регулярное выражение, у вас есть цель: принимать URL-адреса, принимать электронные письма, извлекать токены из кода и т. Д. Я бы переопределил вопрос следующим образом: учитывая базу знаний и семантику для регулярного выражения, вычислим наименьшее регулярное выражение.Это делает шаг вперед, потому что у вас есть естественный язык, пытающийся объяснить общее выражение, и мы все знаем, как это становится неоднозначным!Вы должны иметь некоторое семантическое объяснение.Без этого лучшее, что вы можете сделать для примеров, - это вычислить регулярное выражение, которое охватывает всю строку из списка ok.

Алгоритм покрытия:

Заполнить Ok List
Заполнить Not ok List
Проверка на повторы
Проверка на противоречия (одна и та же строка не может быть в обоих списках)
Создание детерминированных конечных автоматов (DFA) из списка Ok, где строки из списка являются конечными состояниями
Упрощение DFA путемустранение повторяющихся состояний.([1] 4.4)
Преобразование DFA в регулярное выражение.([1] 3.2.2)
Список тестов Ok и список Not ok


[1] Введение в теорию автоматов, язык и вычисления.Дж. Хопкрофт, Р. Мотвани, Дж. Д. Уллман, 2-е издание, Pearson Education.

PS

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

0 голосов
/ 16 сентября 2010

RegexBuilder , похоже, обладает многими функциями, которые вы ищете.

0 голосов
/ 07 сентября 2010

Вы можете попытаться использовать базовый алгоритм вывода, который использовался в других приложениях. Я реализовал очень базовый принцип построения конечного автомата. Тем не менее, это только положительные образцы. Исходный код на http://github.com/mvaled/inferdtd

Должен быть заинтересован AutomataInferrer.py, который очень прост.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...