2009-08-03 27 views
6

Kullanıcı girdisini Getops kullanan küçük bir program yazıyorum ve buna dayanarak, program ya bir metne göre bir deseni eşleştirmeye ya da eşleştirilen metnin yerine geçmeye çalışacaktır.Perl qr // ve yerine koyma

Yapmakta olduğum sorun, ikame bölümünü işe yaratamam. Man sayfalarında qr // girişine bakıyorum: http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators ama onunla hiç şansım yok. Kodumu tam olarak bu durumda dokümanlar gibi modellemeye çalıştım. Bir eşleşme düzenini derledim ve bunu bir ikame yerine koyuyorum.

Birisi yanlış gittiğime işaret edebilir mi?

İşte

ben bakıyorum ne (bu kişisel kullanım için sadece küçük bir script, çok fazla güvenlik konusunda endişe etmeyin): "Ben -r ile çalıştırdığınızda

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 [email protected]; 
    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 

/mat/“-i ve 'mat' metnini değiştirerek, 'mat' metnini yazınız, başarısız oluyor. Bu neden?

DÜZENLEME: cevaplar çocuklar için

teşekkürler! Bu gerçekten çok yardımcı oldu. Her iki önerinizi de problemin çözümünde bir araya getirdim./G bayrağını biraz farklı tutmalıyım. -r "matt" değil -r "/matt/" ile

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 

cevap

11

Kaos dikkat çekerken, qr//'u kullanarak bazı zorluklarla karşılaşacaksınız. Deseni önceden derlemeniz gerekiyor mu? Değilse, böyle bir strateji işe yarayabilecek: yanıtta

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

Güncelleme Yeni kod için: Eğer böyle bir yaklaşım kullanarak düşünebilirsiniz:

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

Ahh, çok iyi '(? seçmesi: pat) '. Bunu her zaman unutursam yapabilirsin. – chaos

7

Run it: İşte çalışan örneğidir. Seçenek dizginizde desen sınırlayıcılarına gereksinim duymanıza gerek yoktur. Tırnak işaretleri, qr'unuzdaki sınırlayıcılardır. Yani aslında etrafınızdaki eğik çizgileri olan matt'u arıyor, istediğiniz şekilde değil. Perl'e kaynak kodunda olduğu gibi desen dizgeni işlemesini söylemek için alıntıları kullanmaya çalışıyorsun, ama maalesef bunu yapamazsın.

Diğer tüm seçenekler için yaptığınız tüm bu şablonlar da işe yaramaz. Bunları yapmak istiyorsanız, regex'i derleme şeklinizi değiştirmeniz gerekir. Böyle bir şey /i ve /s için bunu yapmak olabilir: Değiştirmek/arama alternatif bir bölüm desteklemek gerekir

my $compd_pattern = qr/$pattern/ or die [email protected]; 
$compd_pattern = qr/$compd_pattern/i if $options{i}; 
$compd_pattern = qr/$compd_pattern/s if $options{s}; 

/g için. /g, qr// için geçerli bir değiştirici değildir.