Чи можливо комп’ютеру «вивчити» регулярний вираз на наданих користувачем прикладах?


95

Чи можливо комп’ютеру «вивчити» регулярний вираз на наданих користувачем прикладах?

Для уточнення:

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

Це можливо? Чи існують алгоритми, ключові слова тощо, за якими я можу погуглити?

EDIT : Дякую за відповіді, але мене не цікавлять інструменти, які надають цю функцію. Я шукаю теоретичну інформацію, таку як статті, навчальні посібники, вихідний код, назви алгоритмів, щоб я міг створити щось для себе.


4
Я здивований, що ніхто не згадував Regex :: PreSuf
tripleee

Відповіді:


44

Книга Вступ до теорії обчислювального навчання містить алгоритм вивчення скінченного автомата. Оскільки кожна регулярна мова еквівалентна кінцевому автомату, можна вивчити деякі регулярні вирази за допомогою програми. Кернс і Валіант показують деякі випадки, коли неможливо вивчити кінцевий автомат. Пов'язаною проблемою є вивчення прихованих Марковських моделей , які є імовірнісними автоматами, які можуть описати послідовність символів. Зверніть увагу, що більшість сучасних "регулярних виразів", що використовуються в мовах програмування, насправді сильніші за регулярні мови, а тому інколи важче їх вивчити.


43

Так, можливо, ми можемо генерувати регулярні вирази з прикладів (текст -> бажані витяги). Це діючий онлайн-інструмент, який виконує цю роботу: http://regex.inginf.units.it/

Інтернет-інструмент Regex Generator ++ генерує регулярний вираз із наведених прикладів за допомогою алгоритму пошуку GP. Алгоритм GP керується багатооб'єктивною придатністю, що призводить до вищої продуктивності та спрощення структури рішень (Razor Occam). Цей інструмент є демонстративним додатком лабораторії Machine Lerning, Трієстський університет (Університет університету в Трієсті). Будь ласка, перегляньте відеоурок тут .

Це дослідницький проект, тому ви можете прочитати про використовувані алгоритми тут .

Ось! :-)

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

"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"

Номер телефону не є ідентифікатором товару, це може бути важливим доказом.


4
Це має бути найкращою відповіддю. Це можливо, і це демонструє це. Джерело доступне тут: 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 дозволяє використовувати прості англійські будівельні блоки. Але він не може створити для вас опис високого рівня, оскільки він не може магічно знати, коли слід узагальнювати ваші приклади, а коли ні.

Безумовно, можна створити інструмент, який використовує зразок тексту разом із рекомендаціями, наданими користувачем, для створення регулярного виразу. Важкою частиною проектування такого інструменту є те, як він запитує у користувача керівну інформацію, яка йому потрібна, не роблячи інструмент важчим для засвоєння, ніж самі регулярні вирази, і не обмежуючи інструмент звичайними робочими регулярними виразами або простими регулярними виразами.


Ви праві, багато алгоритмів навчання, які я знайшов після розміщення мого запитання, вимагають позитивної та негативної інформації. Наскільки я розумію, явний "опис вищого рівня" не потрібен, оскільки користувач надає його, відповідаючи на запитання.
Даніель Ріковський 07.03.09

Якщо інструмент задає питання, тоді поєднання запитань та відповідей дають опис вищого рівня. Якість таких інструментів багато в чому залежить від запитань, які вони задають.
Ян Гойваерц,

Це дурне, бо якщо ви подали ще один приклад, то ви можете відсіяти деякі з цих можливостей. Подальший приклад відсіває більше.
Cris

2
@Cris: Принцип залишається незалежно від кількості зразків, які ви надаєте. Це просто змінює можливості. Наприклад, додавши 123456 зміни # 2 до (\ d) \ 1 {5} | 123456 та # 3 до [19] {6} | 123456. Або це може змінити № 3 на [1-69] {6}. Можливо, навіть бажаний зразок відповідав би 6 однаковим цифрам або 6 цифрам, де кожна цифра на одну більша за попередню цифру. Навіть якщо ви надаєте 10000 зразків 6-значних чисел, програма не може розрізнити # 1, # 4, # 5 або # 6 без додаткових вказівок користувача.
Ян Гойваерц,

Я вважаю, що цю проблему легко вирішити наступним чином: Програма намагається бути якомога загальнішою (в межах розумного), а потім надає вам приклади інших речей, які, на її думку, відповідають. Просто сказавши "так" і "ні" запропонованим збігам, ви могли б допомогти йому зрозуміти межі того, що ви насправді намагаєтеся захопити. Я хотів би бачити інструмент у текстовому редакторі, який використовував цю концепцію та пропонував збіги з поточно відкритого файлу.
Jon

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 - Насправді це досить просто. Просто не вкладайте жодного негативного прикладу в побудований регулярний вираз, і вони будуть відхилені. Пам'ятайте, що той, який будує код, відповідає лише позитивному прикладу; негативні приклади (і будь-що інше) виключені за визначенням!
Даніель Ле Чемінант

Даніель має рацію. Без опису вищого рівня, список альтернатив - це все, що можна послідовно і точно зробити з переліку прикладів.
Ян Гойварц

6

Я вважаю, що цей термін - "індукція". Ви хочете навести звичайну граматику.

Я не думаю, що це можливо з кінцевим набором прикладів (позитивних чи негативних). Але, якщо я правильно згадую, це можна зробити, якщо є Oracle, до якого можна звернутися. (В основному вам слід дозволити програмі задавати користувачеві запитання так / ні, поки вона не буде змістом.)


Так, це те, що я хочу зробити, запитайте у користувача інтерактивно.
Даніель Ріковський, 06

Посилання Ювала Ф, здається, те, що я мав на увазі, я б запропонував поглянути на них.
Джей Комінек 06.03.09

5

Можливо, вам захочеться трохи пограти з цим веб-сайтом, він досить крутий і здається, що він робить щось подібне до того, про що ви говорите: http://txt2re.com


4

Існує мова, присвячена подібним проблемам, заснована на prolog. Це називається прогол .

Як зазначали інші, основною ідеєю є індуктивне навчання, яке часто називають ILP ( індуктивне логічне програмування ) в колах ШІ.

Друге посилання - це стаття wiki про ILP, яка містить багато корисного вихідного матеріалу, якщо ви хочете дізнатись більше про тему.


2

@Yuval правильний. Ви дивитесь на обчислювальну теорію навчання, або "індуктивний висновок".

Питання складніше, ніж ви думаєте, оскільки визначення поняття "вчитися" є нетривіальним. Одним із загальноприйнятих визначень є те, що учень може виплюнути відповіді, коли хоче, але врешті-решт, він повинен або припинити виплювати відповіді, або завжди виплюнути ту саму відповідь. Це передбачає нескінченну кількість входів і абсолютно не гарантує, коли програма прийме своє рішення. Крім того, ви не можете сказати, коли він прийняв своє рішення, оскільки пізніше він все одно може вивести щось інше.

За цим визначенням, я майже впевнений, що звичайні мови можна вивчити. За іншими визначеннями, не стільки ...


2

Я провів деякі дослідження в Google та CiteSeer і виявив такі методи / роботи:

Крім того, перспективним видається "Вивчення регулярних наборів за запитами та контрприкладами" Дани Англуін, але мені не вдалося знайти версію для PS чи PDF, лише цитати та роботи семінару.

Здається, це хитра проблема навіть на теоретичному рівні.


0

Якщо людині можливо вивчити регулярний вираз, то це принципово можливо для програми. Однак цю програму потрібно буде правильно запрограмувати, щоб мати можливість вчитися. На щастя, це досить обмежений простір логіки, тому воно не було б таким складним, як викладання програми, щоб мати можливість бачити предмети чи щось подібне.


1
Неправда, вам слід шукати проблеми, які не можна вирішити на машинах Тьюрінга.
Стівен Куріал

Чесно кажучи, я сказав, що якщо людина може навчитися REGEX, то машина може. Я не мав на увазі це взагалі.
cjk

@scurial Я не думаю, що є проблеми, які люди довели, що їх можна вирішити, але на машинах Тьюрінга не можна вирішити, чи не так?
Sunny88
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.