2013-07-30 2 views
8

Можно ли проверить, будет ли данное регулярное выражение соответствовать любой строке? В частности, я ищу функцию matchesEverything($regex), которая возвращает true, если $regex будет соответствовать любой строке.Проверьте, будет ли данное регулярное выражение соответствовать чему-либо

Я полагаю, что это эквивалентно запросу: «Если задано регулярное выражение r, существует ли строка, которая не соответствует r?» и я не думаю, что это разрешимо, не помещая границы на множество «всех строк». I.e., если я предполагаю, что строки никогда не будут содержать «блаббаль», тогда я могу просто проверить, соответствует ли r «бла-бла». Но что, если таких границ нет? Мне интересно, можно ли решить эту проблему, если регулярное выражение r эквивалентно .*.

+4

Я считаю, что это эквивалентно [Проблема с остановкой] (http://en.wikipedia.org/wiki/Halting_problem). Возможно, не удастся написать алгоритм, чтобы определить, эквивалентно ли произвольное регулярное выражение '. *' –

+0

. Регулярные выражения с обратными ссылками и backrefs, но без интерполяции кода, должны быть подмножеством или равными контекстно-зависимым грамматикам. Решение этих языков не является завершением Тьюринга, поэтому этот вопрос не должен быть эквивалентен проблеме остановки. * Если *, учитывая CSG, мы можем создать строку этого языка, заменив правила, тогда мы можем применить запрещенную подстановку, создав таким образом строку, которая отсутствует на нашем языке. К сожалению, я не знаю, так ли это, и я не смог бы набросать это доказательство. – amon

+2

Это называется «Проблема пустоты» и разрешима для DFA/NFA (т.е. регулярные выражения без обратных ссылок/обратных ссылок). Http://www.cs.miami.edu/~ogihara/csc527/new04-1.pdf Для regexes с backrefs (контекстно-зависимые грамматики), проблема пустоты неразрешима.(Я не могу найти доказательство прямо сейчас, но это часто упоминается в литературе) – rmmh

ответ

12

Это не точно ответить на ваш вопрос, но мы надеемся, объясняет немного, почему простой ответ трудно найти:

Во-первых, термин «регулярное выражение» немного мутная, так что просто уточнить, мы имеют:

  • «Строгие» регулярные выражения, эквивалентные детерминированным конечным автоматам (DFA).
  • Perl-совместимые регулярные выражения (PCRE), которые добавляют кучу колоколов и свистов, таких как lookaheads, backreferences и т. Д. Они реализованы и на других языках, таких как Python и Java.
  • Фактические регулярные выражения Perl, которые могут стать еще более сумасшедшими, включая произвольный код Perl, через конструкцию ?{...}.

Я думаю, что эта проблема разрешима для строгих регулярных выражений. Вы просто создаете соответствующий DFA и просматриваете этот граф, чтобы узнать, есть ли какой-либо путь к состоянию, не принимающему. Но это не помогает регулярному выражению «real world», обычно это PCRE.

Я не думаю, что PCRE является Turing-complete (хотя я не знаю - см. Этот вопрос тоже: Are Perl regexes turing complete?). Если бы это было так, то я думаю, как прокомментировал Джим Гаррисон, это в основном проблема с остановкой. Это не так просто превратить их в DFA, либо сделать этот метод бесполезным ...

У меня нет ответа для PCRE, но имейте в виду, что вышеупомянутые конструкции (обратные ссылки и т. Д.), Полагаю, что это будет довольно сложно. Хотя я не решаюсь сказать «невозможно».

Подлинное Perl регулярное выражение с ?{...} в нем определенно Turing-complete, поэтому есть драконы, и я думаю, вам не повезло.

+0

отличный ответ. вы укрепили то, о чем я думал. для случая использования, к которому я обращаюсь, любые фактические регулярные выражения perl будут тем, о чем я забочусь. почти что угодно, где 'eval {'xx' = ~ m/$ regex/i; } 'приводит к успешной оценке. –

Смежные вопросы