Вопрос

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

У меня проблема в том, что я не могу заставить замещающую часть работать. Я просматриваю запись qr // на страницах руководства: 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 \n\t{$text} Failed. ";
    }
} #end R FLAG

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

РЕДАКТИРОВАТЬ:

Спасибо за ответы, ребята! Это было действительно очень полезно. Я объединил оба ваших предложения в рабочее решение проблемы. Я должен обрабатывать флаг / 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 \n\t{$text} Failed. ";
        }
    }
    else{
        if($text =~ s/(?$pattern_flags:$pattern)/$rep_text/){ #if the text matched or whatever
            print $text;
        }
        else{
            print "$pattern on \n\t{$text} Failed. ";
        }
    }
} #end R FLAG
Это было полезно?

Решение

Как указывает хаос, вы столкнетесь с некоторыми трудностями при использовании 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 { 

Как указывает хаос, вы столкнетесь с некоторыми трудностями при использовании 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/;

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

<*>[0] =~ s/(?$flags:$patt)/$rep/g } : sub {

Как указывает хаос, вы столкнетесь с некоторыми трудностями при использовании 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/;

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

<*>[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 // .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top