質問

Getopsを使用してユーザー入力を取得する小さなプログラムを作成しています。それに基づいて、プログラムはパターンとテキストを一致させるか、一致したテキストをテキストに置き換えます。

私が抱えている問題は、置換部分を機能させることができないことです。 manページの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&quot; / matt /&quot;で実行すると-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&quot; / matt /&quot; ではなく、 -r&quot; matt&quot; で実行します。オプション文字列にパターン区切り文字を指定する必要はありませんし、実際には指定できません。引用符は、 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