Все ли регулярные выражения останавливаются?

Есть ли какое-нибудь регулярное выражение, которое для некоторой входной строки будет вечно искать совпадение?


person Tom Lehman    schedule 06.08.2009    source источник
comment
... и можете ли вы написать программу, которая определяет, остановится ли регулярное выражение для заданного ввода?   -  person Michael Myers    schedule 07.08.2009
comment
Для бонусных отметок - с помощью регулярного выражения!   -  person Martin Beckett    schedule 07.08.2009
comment
Конечно, mmyers и mgb - просто запустите это для ввода, конкатенированного с регулярным выражением: /.*/ - соответствие означает остановку, отсутствие совпадения означает, что это не так. :П   -  person Amber    schedule 07.08.2009
comment
mmyers: программа довольно простая. Я представлю это на python: True. --- Что касается принятия строки, ну, это запустить регулярное выражение r на входе i, вернуть то, что оно возвращает.   -  person agorenst    schedule 07.08.2009


Ответы (8)


Для конечного ввода не существует формального регулярного выражения, которое не остановилось бы.

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

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

Теперь, если ввод бесконечен, можно найти тривиальные регулярные выражения, которые никогда не остановятся. Например, «.*».

person Daniel C. Sobral    schedule 06.08.2009
comment
Единственная придирка: их называют детерминированными конечными автоматами, а не определенными. В отличие от (по иронии судьбы, эквивалентных) недетерминированных конечных автоматов. - person agorenst; 07.08.2009
comment
@Agor: Я ненавижу, когда я это делаю. Я хорошо знаю правильное имя, но по некоторым причинам я всегда набираю неправильное имя. :-( - person Daniel C. Sobral; 07.08.2009

Формальное регулярное выражение - это фактически метод описания детерминированного конечного автомата для анализа строк. Регулярное выражение «совпадает», если DFA переходит в состояние приема в конце ввода. Поскольку DFA считывает свой ввод последовательно, он всегда будет останавливаться, когда достигнет конца ввода, и, есть ли совпадение, просто вопрос проверки того, в каком состоянии DFA он останавливается.

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

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

person Amber    schedule 06.08.2009

Я полагаю, невозможно найти регулярное выражение, которое не останавливается.

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

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

Итак, он остановится.

person Sinan Taifour    schedule 06.08.2009

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

person agentofuser    schedule 06.08.2009

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

Я не думаю, что здесь действительно применима остановка, как проницательно отметили другие комментаторы этого поста. http://en.wikipedia.org/wiki/Halting_problem

person Robert Greiner    schedule 06.08.2009
comment
Невозможно создать программу, которая для каждой возможной программы сообщала вам, останавливается она или нет. Но это не значит, что вы не можете сделать это для подмножества. Может быть, регулярные выражения - одно из таких подмножеств, но я не знаю. - person agentofuser; 07.08.2009
comment
Обращение к проблеме остановки здесь не очень полезно; Алгоритм, используемый для сопоставления RE, является особым алгоритмом, интересная особенность проблемы остановки состоит в том, чтобы решить ее для всех пар программа-ввод. - person Sinan Taifour; 07.08.2009
comment
да, это то, что я пытался сказать в своем ответе. - person Robert Greiner; 07.08.2009

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

Например, если в языке допускается a * b, и у вас есть бесконечно длинная строка из «a», тогда да, регулярное выражение никогда не остановится. Однако на практике это невозможно.

person bkritzer    schedule 06.08.2009

да.

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

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

http://en.wikipedia.org/wiki/Finite_state_machine

person Unknown    schedule 06.08.2009

+1 за ответ Даниэля: все конечные входы вызывают остановку истинного регулярного выражения (то есть без обратных ссылок или других функций, отличных от регулярного), а регулярные выражения эквивалентны DFA.

Бонус: сопоставление регулярных выражений может быть простым и быстрым (но медленным в Java, Perl, PHP, Python, Ruby, ...)

http://swtch.com/~rsc/regexp/regexp1.html

Обратите внимание, что два графика в верхней части статьи имеют разные масштабы по оси Y: один - секунды, другой - микросекунды!

person Peyton    schedule 13.05.2010