Pergunta

Eu estou escrevendo um pequeno programa que leva a entrada do usuário usando Getops, e com base nele, o programa quer tentar corresponder a um padrão contra algum texto, ou o texto substituto para o combinado.

O problema que estou tendo é que eu não posso começar a parte substituição ao trabalho. Eu estou olhando para a qr // entrada nas páginas man: http : //perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators mas eu não estou tendo nenhuma sorte com isso. Eu tentei modelar o meu código exatamente como os docs neste caso. Eu compilar um padrão de jogo, e substituir isso em uma substituição.

Alguém poderia apontar onde eu estou indo errado? (Não se preocupe com a segurança muito, este é apenas um pequeno script para uso pessoal)

Aqui está o que eu estou olhando para:

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

Quando eu executá-lo com -r "/ mate /" -i, e digite o texto de substituição 'Mateus', sobre o texto 'mate', ele falhar. Por que isso?

EDIT:

Obrigado pelas respostas caras! Isso foi realmente muito útil. Eu combinei ambas as sugestões em uma solução de trabalho para o problema. Eu tenho que lidar com a / g bandeira um pouco diferente. Aqui está o exemplo de trabalho:

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
Foi útil?

Solução

Como o caos aponta, você vai encontrar algumas dificuldades usando qr//. Você realmente precisa de pré-compilar o padrão? Se não, uma estratégia como este trabalho poder:

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/;

Atualização em resposta ao seu novo código : você pode considerar o uso de uma abordagem como esta:

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...";
}

Outras dicas

Executar com -r "matt", não -r "/matt/". Você não precisa, e de fato não pode, delimitadores padrão de alimentação na sua expressão de opção. As citações são os delimitadores na sua qr. Por isso é realmente procurando matt com barras em torno dele, a maneira como você está funcionando, o que não é o que você quer. Você está tentando usar as aspas para dizer Perl para tratar sua cadeia padrão como se fosse código fonte, mas, infelizmente, você não pode fazer isso.

Todos aqueles padrão acrescenta que você está fazendo para as outras opções também não trabalho. Você precisa mudar a maneira de compilar o regex se você quiser fazer tudo isso. Algo como isso pode fazê-lo por /i e /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};

Para /g você vai precisar para suportar uma versão alternativa da busca / substituição. /g não é um modificador válida para qr//.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top