문제

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로 실행하고 텍스트 'matt'에 대체 텍스트 'Matthew'를 입력하면 실패합니다. 왜 이런거야?

편집하다:

답변 주셔서 감사합니다! 정말 도움이되었습니다. 나는 두 가지 제안을 문제에 대한 작업 솔루션으로 결합했습니다. /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 { $_[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에게 패턴 문자열을 소스 코드처럼 취급하도록 지시하려고하지만 불행히도 그렇게 할 수는 없습니다.

다른 옵션에 대해 수행하는 모든 패턴도 작동하지 않습니다. 모든 작업을 수행하려면 Regex를 컴파일하는 방식을 변경해야합니다. 이와 같은 일이 그렇게 할 수 있습니다 /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