Perl qr / / и замена

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

проблема в том, что я не могу заставить часть замены работать. Я смотрю на запись qr// на man-страницах:http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators но мне не повезло с этим. Я попытался смоделировать свой код точно так же, как документы в этом случае. Я компилирую шаблон соответствия и заменяю его заменой.

может кто-нибудь указать, где я буду неправильно? (Не беспокойтесь о безопасности слишком много, это всего лишь небольшой скрипт для личного использования)

вот на что я смотрю:

if($options{r}){

    my $pattern = $options{r};
    print "nEnter Replacement text: ";
    my $rep_text = <STDIN>;

    #variable grab, add flags to pattern if they exist.
    $pattern .= 'g' if $options{g};
    $pattern .= 'i' if $options{i};
    $pattern .= 's' if $options{s};


    #compile that stuff
    my $compd_pattern = qr"$pattern" or die $@;
    print $compd_pattern; #debugging

    print "Please enter the text you wish to run the pattern on: ";
    my $text = <STDIN>;
    chomp $text;    

    #do work and display
    if($text =~ s/$compd_pattern/$rep_text/){ #if the text matched or whatever
        print $text;
    }
    else{
        print "$compd_pattern on nt{$text} Failed. ";
    }
} #end R FLAG

когда я запускаю его с-r "/ matt / "- i, и введите текст замены "matthew", на тексте "matt", он терпит неудачу. Почему так?

EDIT:

Спасибо за ответы ребята ! Это было очень полезно. Я объединил оба ваших предложения в рабочее решение проблемы. Я должен обращаться с флагом /g немного по-другому. Вот рабочий пример:

if($options{r}){

    my $pattern = $options{r};
    print "nEnter Replacement text: ";
    my $rep_text = <STDIN>;
    chomp $rep_text;

    #variable grab, add flags to pattern if they exist.

    my $pattern_flags .= 'i' if $options{i};
    $pattern_flags .= 's' if $options{s};

    print "Please enter the text you wish to run the pattern on: ";
    my $text = <STDIN>;
    chomp $text;    

    #do work and display
    if($options{g}){
        if($text =~ s/(?$pattern_flags:$pattern)/$rep_text/g){ #if the text matched or whatever (with the g flag)
            print $text;
        }
        else{
            print "$pattern on nt{$text} Failed. ";
        }
    }
    else{
        if($text =~ s/(?$pattern_flags:$pattern)/$rep_text/){ #if the text matched or whatever
            print $text;
        }
        else{
            print "$pattern on nt{$text} Failed. ";
        }
    }
} #end R FLAG

2 ответов


как указывает хаос, вы столкнетесь с некоторыми трудностями, используя qr//. Вам действительно нужно предварительно скомпилировать шаблон? Если нет, такая стратегия может сработать:

my $pattern      = 'matt';
my $text         = 'Matt';
my $rep_text     = 'Matthew';
my $pattern_opts = 'i';

print $text, "\n" if $text =~ s/(?$pattern_opts:$pattern)/$rep_text/;

обновление в ответ на ваш новый код: вы можете использовать такой подход:

my ($orig, $patt, $rep, $flags) = qw(FooFooFoo foo bar ig);

my $make_replacement = $flags =~ s/g//        ?
    sub { $_[0] =~ s/(?$flags:$patt)/$rep/g } :
    sub { $_[0] =~ s/(?$flags:$patt)/$rep/  }
;

if ( $make_replacement->($orig) ){
    print $orig;
}
else {
    print "Failed...";
}

С -r "matt", а не -r "/matt/". Вам не нужно и фактически не может предоставлять разделители шаблонов в строке параметров. Кавычки являются разделителями в вашем qr. Так что это на самом деле ищет matt С косыми чертами вокруг него, как вы его запускаете, что не то, что вы хотите. Вы пытаетесь использовать кавычки, чтобы сказать Perl, чтобы обработать вашу строку шаблона, как исходный код, но, к сожалению, вы не можете этого сделать.

все эти шаблоны, которые вы делаете для других вариантов также не будет работать. Вам нужно будет изменить способ компиляции регулярного выражения, если вы хотите сделать все это. Что-то вроде этого может сделать это для /i и /s:

my $compd_pattern = qr/$pattern/ or die $@;
$compd_pattern = qr/$compd_pattern/i if $options{i};
$compd_pattern = qr/$compd_pattern/s if $options{s};

на /g вам нужно будет поддерживать альтернативную версию поиска / замены. /g не действует модификатор qr//.