Question

Je suis en train d’écrire un petit programme qui prend en charge l’entrée de l’utilisateur à l’aide de Getops. Le programme essaiera alors de faire correspondre un modèle à du texte ou de remplacer le texte correspondant.

Le problème que je rencontre est que je ne parviens pas à obtenir la partie substitution. Je regarde l’entrée qr // des pages de manuel: http : //perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators mais je n'ai aucune chance avec cela. J'ai essayé de modéliser mon code exactement comme les docs dans ce cas. Je compile un modèle de correspondance et le substitue à une substitution.

Quelqu'un pourrait-il indiquer où je vais mal? (Ne vous inquiétez pas de la sécurité, ce n’est qu’un petit script à usage personnel)

Voici ce que je regarde:

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

Quand je l'exécute avec -r " / matt / " -i, et entrez le texte de remplacement 'matthew', sur le texte 'matt', il échoue. Pourquoi est-ce?

EDIT:

Merci les réponses les gars! C'était vraiment très utile. J'ai combiné vos deux suggestions dans une solution de travail au problème. Je dois manipuler le drapeau / g un peu différemment. Voici l'exemple de travail:

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
Était-ce utile?

La solution

Comme le chaos l’indique, vous rencontrerez des difficultés avec qr // . Avez-vous vraiment besoin de précompiler le motif? Sinon, une stratégie comme celle-ci pourrait fonctionner:

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

Mise à jour en réponse à votre nouveau code : vous pouvez envisager d'utiliser une approche semblable à celle-ci:

my ($orig, $patt, $rep, $flags) = qw(FooFooFoo foo bar ig);

my $make_replacement = $flags =~ s/g//        ?
    sub { 

Comme le chaos l’indique, vous rencontrerez des difficultés avec qr // . Avez-vous vraiment besoin de précompiler le motif? Sinon, une stratégie comme celle-ci pourrait fonctionner:

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

Mise à jour en réponse à votre nouveau code : vous pouvez envisager d'utiliser une approche semblable à celle-ci:

<*>[0] =~ s/(?$flags:$patt)/$rep/g } : sub {

Comme le chaos l’indique, vous rencontrerez des difficultés avec qr // . Avez-vous vraiment besoin de précompiler le motif? Sinon, une stratégie comme celle-ci pourrait fonctionner:

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

Mise à jour en réponse à votre nouveau code : vous pouvez envisager d'utiliser une approche semblable à celle-ci:

<*>[0] =~ s/(?$flags:$patt)/$rep/ } ; if ( $make_replacement->($orig) ){ print $orig; } else { print "Failed..."; }

Autres conseils

Exécutez-le avec -r "matt" et non pas -r "/ matt /" . Vous n'avez pas besoin, et en fait ne pouvez pas, fournir de délimiteurs de modèle dans votre chaîne d'option. Les guillemets sont les délimiteurs de votre qr . Il s’agit donc de rechercher matt avec des barres obliques, la façon dont vous l’exécutez, ce qui n’est pas ce que vous voulez. Vous essayez d'utiliser les guillemets pour indiquer à Perl de traiter votre chaîne de modèle comme s'il s'agissait d'un code source, mais vous ne pouvez malheureusement pas le faire.

Tous ces ajouts que vous faites pour les autres options ne fonctionneront pas non plus. Si vous voulez faire tout cela, vous devrez changer la manière dont vous compilez la regex. Quelque chose comme cela pourrait le faire pour / i et / 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};

Pour / g , vous devez prendre en charge une autre version de la recherche / remplacement. / g n'est pas un modificateur valide pour qr // .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top