Сопоставьте регулярное выражение с другим регулярным выражением в Perl

Я хочу выяснить, является ли данное регулярное выражение подмножеством более крупного регулярного выражения. Например, учитывая большее регулярное выражение ((a*)(b(a*))), я хочу найти, соответствует ли ему регулярное выражение, такое как (aab.*) или (a.*). Я разрабатываю программу, в которой мне нужно найти все подстроки заданной длины, которые могут быть сформированы из заданного регулярного выражения.

$count=0;
$len=0;
sub match{

    my $c=$_[1];
    my $str=$_[0];
    my $reg=$_[2];
    #if($str.".*"!~/^$reg$/){
    #       return;
    #}

    if($c==$len){
            if($str=~/^reg$/){
                    $count++;
            }
            return;
    }

    my $t=$str.'a';
    &match($t,$c+1,$reg);
    my $t=$str.'b';
    &match($str.'b',$c+1,$reg);
 }
 for(<>){
    @arr=split(/\s/,$_);
    $len=$arr[1];
    &match('a',1,$arr[0]);
    &match('b',1,$arr[0]);
    print $count;
 }

Поэтому я подумал, что буду запускать строки заданной длины с помощью рекурсии, и когда размер строки достигнет желаемой длины, я сравним его с исходным значением exp. Это отлично работает для небольших подстрок, но приводит к переполнению стека для больших подстрок. Поэтому я подумал, что при генерации части самой строки я буду проверять выражение на заданное reg exp. Но это не сработало. Для приведенного выше регулярного выражения ((a*)(b(a*))), если мы сравним его с частичной строкой (aa), произойдет сбой, поскольку регулярное выражение не совпадает. Поэтому, чтобы это сработало, мне нужно сравнить два регулярных выражения, добавив .* после каждой частичной подстановки. Я пытался найти ответ в Интернете, но безуспешно.

Я попробовал следующий код, но, естественно, это не удалось. Может ли кто-нибудь предложить другой подход.

if("a.*"=~/((a*)(b(a*)))/){
      print match;
 }

Но здесь первая часть считается реальной строкой. Можете ли вы помочь мне преобразовать код, чтобы я мог сравнивать (a. *) как регулярное выражение, а не как строку.


person coder hacker    schedule 22.12.2013    source источник
comment
У меня такое ощущение, что сравнение подобных регулярных выражений в целом может быть невычислимым, особенно если вы разрешаете рекурсивные регулярные выражения, как, я думаю, регулярные выражения Perl.   -  person murgatroid99    schedule 22.12.2013
comment
@ murgatroid99 Значит, эта проблема неразрешима. Должен ли я перейти на другой язык программирования.   -  person coder hacker    schedule 22.12.2013
comment
Я не говорю, что решение этой проблемы определенно неразрешимо, но сопоставление регулярных выражений намного сложнее, чем то, что вы видели (например, как (a?b?)+ и (b?a?)+) соответствуют всем последовательностям a и b). Если она неразрешима, то, вероятно, неразрешима в принципе, и переключение языков не поможет.   -  person murgatroid99    schedule 22.12.2013


Ответы (1)


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

Теперь сравните положение, в котором совпадение остановилось, если оно равно длине вашей строки и эквивалентно регулярному выражению str(.*). Я читал, что это можно сделать на некоторых других языках, но я не уверен насчет perl.

person Community    schedule 22.12.2013