Может ли компьютер «выучить» регулярное выражение на примерах, предоставленных пользователем?

95

Может ли компьютер «выучить» регулярное выражение на примерах, предоставленных пользователем?

Чтобы уточнить:

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

Является ли это возможным? Есть ли алгоритмы, ключевые слова и т. Д., По которым я могу использовать Google?

РЕДАКТИРОВАТЬ : Спасибо за ответы, но меня не интересуют инструменты, которые предоставляют эту функцию. Я ищу теоретическую информацию, такую ​​как статьи, руководства, исходный код, названия алгоритмов, чтобы я мог создать что-то для себя.

Даниэль Риковски
источник
4
Я удивлен, что никто не упомянул Regex :: PreSuf
tripleee

Ответы:

44

Книга Введение в теорию вычислительного обучения содержит алгоритм обучения конечного автомата. Поскольку любой регулярный язык эквивалентен конечному автомату, некоторые регулярные выражения можно выучить с помощью программы. Кернс и Валиант показывают некоторые случаи, когда невозможно изучить конечный автомат. Смежная проблема - изучение скрытых марковских моделей , которые представляют собой вероятностные автоматы, которые могут описывать последовательность символов. Обратите внимание, что большинство современных «регулярных выражений», используемых в языках программирования, на самом деле сильнее обычных языков, и поэтому иногда их труднее выучить.

Юваль Ф
источник
44

Да, это возможно, мы можем генерировать регулярные выражения из примеров (текст -> желаемые извлечения). Это рабочий онлайн-инструмент, который выполняет свою работу: http://regex.inginf.units.it/

Онлайн-инструмент Regex Generator ++ генерирует регулярное выражение из предоставленных примеров, используя алгоритм поиска GP. Алгоритм GP управляется многокритериальной пригодностью, что приводит к более высокой производительности и более простой структуре решения (бритва Оккама). Этот инструмент является демонстрационным приложением Лаборатории Машин Лернинга, Университет Триеста (Università degli studi di Trieste). Пожалуйста, посмотрите видеоурок здесь .

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

Вот! :-)

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

"The product code is 467-345A" -> "467-345A"
"The item 789-345B is broken"  -> "789-345B"

Парень (человек), глядя на примеры, может сказать: «Коды товаров - это такие вещи, как \ d ++ - 345 [AB]»

Когда код товара более допустим, но мы не предоставили других примеров, у нас нет доказательств, чтобы хорошо понять проблему. При применении созданного человеком решения \ d ++ - 345 [AB] к следующему тексту это не удается:

"On the back of the item there is a code: 966-347Z"

Вы должны предоставить другие примеры, чтобы лучше описать совпадение, а что нет: --ie:

"My phone is +39-128-3905 , and the phone product id is 966-347Z" -> "966-347Z"

Номер телефона не является идентификатором продукта, это может быть важным доказательством.

Фабиано Тарлао
источник
5
Это должен быть главный ответ. Возможно, и это демонстрирует. Источник доступен здесь: github.com/MaLeLabTs/RegexGenerator
rjurney
Ваш пример кодов продуктов иллюстрирует, почему указанному человеку следует найти спецификацию кодов продуктов и написать регулярное выражение на основе спецификации, а не пытаться вывести регулярное выражение из ограниченного набора образцов кодов продуктов (независимо от того, является ли человек или программа пытается вывести регулярное выражение).
Ян Гойвертс,
2
Это правильный способ делать вещи. Мой пример - всего лишь способ концептуально объяснить проблему. Иногда спецификации нет, или парень просто не может написать регулярное выражение (незнание) самостоятельно.
Фабиано Тарлао,
Чтобы быть более точным и недвусмысленным :-), «Это правильный способ делать что-то» -> «Вы правы, это лучший способ делать что-либо, вы всегда должны начинать со спецификаций, когда это возможно»
Фабиано Тарлао,
2
Статья «Вывод регулярных выражений для извлечения текста из примеров» содержит подробное объяснение алгоритма machinelearning.inginf.units.it/publications/…
mimmuz
36

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

Предположим, вы предоставили примеры 111111 и 999999, если компьютер сгенерирует:

  1. Регулярное выражение, соответствующее этим двум примерам: (111111|999999)
  2. Регулярное выражение, соответствующее 6 идентичным цифрам (\d)\1{5}
  3. Регулярное выражение, соответствующее 6 единицам и девяткам [19]{6}
  4. Регулярное выражение, соответствующее любым 6 цифрам \d{6}
  5. Любой из трех вышеупомянутых, с границами слов, например \b\d{6}\b
  6. Любой из первых трех, без цифры перед и после нее, например (?<!\d)\d{6}(?!\d)

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

Если вы не хотите перечислять все возможные совпадения, вам нужно описание более высокого уровня. Именно для этого предназначены регулярные выражения. Вместо того, чтобы предоставлять длинный список из 6-значных чисел, вы просто говорите программе сопоставить «любые шесть цифр». В синтаксисе регулярных выражений это становится \ d {6}.

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

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

Ян Гойвертс
источник
Вы правы, многие алгоритмы обучения, которые я обнаружил после публикации своего вопроса, требуют положительной и отрицательной информации. Насколько я понимаю, явное "высокоуровневое описание" не требуется, потому что пользователь предоставляет его, отвечая на вопросы.
Дэниел Риковски,
Если инструмент задает вопросы, тогда комбинация вопросов и предоставленных ответов формирует описание более высокого уровня. Качество таких инструментов во многом зависит от задаваемых вопросов.
Ян Гойвертс,
Это глупо, потому что, если вы привели другой пример, вы можете отсеять некоторые из этих возможностей. Дальнейший пример устраняет больше.
Крис
2
@Cris: Принцип остается неизменным, независимо от того, сколько образцов вы предоставите. Это просто меняет возможности. Например, добавление 123456 изменяет # 2 на (\ d) \ 1 {5} | 123456 и # 3 на [19] {6} | 123456. Или можно изменить № 3 на [1-69] {6}. Возможно даже, что желаемый шаблон будет соответствовать 6 идентичным цифрам или 6 цифрам, где каждая цифра на единицу больше предыдущей. Даже если вы предоставите 10 000 выборок 6-значных чисел, программа не сможет различить №1, №4, №5 или №6 без дополнительных инструкций пользователя.
Ян Гойвертс
Мне кажется, что эта проблема легко решается следующим образом: программа пытается быть как можно более общей (в пределах разумного), а затем дает вам примеры других вещей, которые, по ее мнению, могут соответствовать. Просто сказав «да» и «нет» предложенным совпадениям, вы можете помочь ему понять границы того, что вы на самом деле пытаетесь захватить. Я хотел бы увидеть инструмент в текстовом редакторе, который использовал бы эту концепцию и предлагал совпадения из текущего открытого файла.
Джон МакКланг
9

Да, конечно «возможно»; Вот псевдокод:

string MakeRegexFromExamples(<listOfPosExamples>, <listOfNegExamples>)
{
   if HasIntersection(<listOfPosExamples>, <listOfNegExamples>)
     return <IntersectionError>

   string regex = "";
   foreach(string example in <listOfPosExamples>)
   {
      if(regex != "")
      {
         regex += "|";
      }
      regex += DoRegexEscaping(example);
   }
   regex = "^(" + regex + ")$";

   // Ignore <listOfNegExamples>; they're excluded by definition

   return regex;
}

Проблема в том, что существует бесконечное количество регулярных выражений, которые будут соответствовать списку примеров. Этот код предоставляет самое простое / самое глупое регулярное выражение в наборе, в основном соответствующее чему-либо в списке положительных примеров (и ничего больше, включая любые отрицательные примеры).

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

Даниэль ЛеШеминант
источник
3
Интересно становится, когда пользователь вводит положительные и отрицательные образцы. Регулярное выражение должно соответствовать положительным образцам и не совпадать с отрицательными.
user55400 06
@blixtor - На самом деле, это довольно просто. Просто не помещайте отрицательные примеры в построенное регулярное выражение, и они будут отклонены. Помните, что тот, который строит код, соответствует только положительному примеру; отрицательные примеры (и все остальное) исключены по определению!
Daniel LeCheminant 06
Даниэль прав. Без высокоуровневого описания список альтернатив - это все, что можно последовательно и точно вывести из списка примеров.
Ян Гойвертс,
6

Я считаю, что это термин «индукция». Вы хотите научить вас правильной грамматике.

Я не думаю, что это возможно с ограниченным набором примеров (положительных или отрицательных). Но, если я правильно помню, это можно сделать, если есть Oracle, с которым можно проконсультироваться. (По сути, вы должны позволить программе задавать пользователю вопросы типа «да / нет», пока она не будет удовлетворена.)

Джей Коминек
источник
Да, это то, что я хочу сделать, интерактивно спросить пользователя.
Дэниел Риковски, 06
Ссылки Юваля Ф., кажется, именно то, что я имел в виду, я бы посоветовал взглянуть на них.
Джей Коминек, 06
5

Возможно, вы захотите немного поиграть с этим сайтом, это довольно круто и похоже, что он делает что-то похожее на то, о чем вы говорите: http://txt2re.com

Чад Берч
источник
4

Для подобных проблем есть язык, основанный на прологе. Это называется прогол .

Как уже упоминали другие, основная идея - это индуктивное обучение, которое в кругах ИИ часто называется ILP ( индуктивное логическое программирование ).

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

Патрос
источник
2

@Yuval прав. Вы смотрите на теорию вычислительного обучения или «индуктивный вывод».

Вопрос сложнее, чем вы думаете, поскольку определение «учиться» нетривиально. Одно из распространенных определений состоит в том, что учащийся может выкладывать ответы, когда захочет, но в конечном итоге он должен либо перестать выплевывать ответы, либо всегда выдавать один и тот же ответ. Это предполагает бесконечное количество входных данных и не дает абсолютно никаких гарантий относительно того, когда программа достигнет своего решения. Кроме того, вы не можете сказать, когда он ПРИНЯЛ свое решение, потому что он все еще может вывести что-то другое позже.

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

Брайан Постоу
источник
2

Я провел небольшое исследование в Google и CiteSeer и нашел следующие методы / статьи:

Также многообещающим кажется «Изучение регулярных множеств на основе запросов и контрпримеров» Даны Англуин, но мне не удалось найти версию в PS или PDF, только цитирование и семинары.

Кажется, это непростая задача даже на теоретическом уровне.

Даниэль Риковски
источник
0

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

cjk
источник
1
Неправда, вам следует искать проблемы, которые невозможно решить на машинах Тьюринга.
Стивен Куриал,
Честно говоря, я сказал, что если человек может выучить REGEX, то и машина может. Я не имел в виду этого вообще.
cjk 05
@scurial Я не думаю, что есть проблемы, которые, как было доказано, решаемы людьми, но неразрешимые на машинах Тьюринга, не так ли?
Sunny88