6

私は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
4

2 に答える 2

10

カオスが指摘しているように、を使用するといくつかの問題が発生し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...";
}
于 2009-08-03T18:10:46.697 に答える
6

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

于 2009-08-03T17:55:51.483 に答える