2008-12-07 4 views
13

Je programme en Perl depuis plusieurs années, même si ce n'est que sporadiquement ma langue maternelle. Parce que je passe souvent des mois sans écrire de perl, je me fie énormément à mon livre Camel Book pour me rappeler comment faire les choses. Cependant, lorsque je copie textuellement des recettes sans comprendre, cela me dérange. Ceci est l'un des plus épineux: A la page 154 de la 3e édition de chameau, il est un exemple pour « modifier les chaînes en passant qui se lit comme suit:À quoi sert l'opérateur de substitution Perl?

($lotr = $hobbit) =~ s/Bilbo/Frodo/g; 

Q1) ce qui se passe ici? Q2) Cette syntaxe quasi-magique est-elle nécessaire pour une opération de base telle que "prendre une chaîne de $ a, la modifier avec une regex, placer le résultat dans $ b"?

Q3) Comment faire cette opération en utilisant la variable par défaut de la boucle comme chaîne initiale?

Excuses d'avance aux rêveurs Perl pour qui ce qui précède semble parfaitement naturel.

Répondre

22

Hmmm ... ($lotr=$hobbit) =~ s/Bilbo/Frodo/g est l'une des nombreuses magies de Perl. Maintenant pour quelques réponses.

Q1) $lotr reçoit la valeur contenue dans $hobbit. Après l'affectation, nous pouvons oublier la variable source. Traiter ($lotr = $hobbit) comme sa propre déclaration, si nous avions écrit:

$lotr = $hobbit; 
$lotr =~ s/Bilbo/Frodo/g; 

à la place. L'expression régulière fonctionne sur $lotr.

Q2) La syntaxe est simplement une version d'une ligne de l'extrait ci-dessus. Pensez-y comme « copier la chaîne de $a, copiez-le dans $b et modifier $b avec l'expression régulière » au lieu de « prendre une chaîne de $a, le modifier avec une expression régulière, le lieu résultat dans $b »

Q3) I Supposons que vous voulez dire le motif par défaut recherche de l'espace par "boucle variable par défaut"? Dans ce cas, il suffit d'utiliser $_ au lieu de $hobbit:

while (<>) { 
    chomp; 
    ($lotr = $_) =~ s/Bilbo/Frodo/g; 
    print "\$lotr = [$lotr]\n"; 
    print "\$_ = [$_]\n"; 
} 

Chose intéressante, la magie var $_ est pas modifié par cette opération. C'est ainsi que vous pouvez conclure que l'affectation passe avant la substitution d'expression régulière et que la substitution n'interagit pas sur l'espace de motif par défaut de quelque façon que ce soit. Et pour les programmeurs expérimentés de Perl ... Je ne connais pas beaucoup de gens qui sont lancés par une partie de la syntaxe Perl, peu importe combien de temps ils l'ont regardé, bien sûr M. Schwartz;)

+0

Cette réponse est correcte. Je le tapais comme cela a été posté. Il (la solution) par le chemin m'a pris une recherche de Google pour trouver. – Paul

+0

@ D.Shawley. Jees mate. D'après ce que vous avez dit plus haut, pourquoi $ _ serait-il modifié? "copiez la chaîne de $ a ($ _) ... dans $ b ($ lotr) et modifiez $ b ($ lotr) avec la regex, placez le résultat dans $ b ($ lotr)". Aucune magie impliquée avec $ _ du tout. –

+0

Je vote pour ceci, pour être la réponse acceptée. –

5

Différentes langues font des choses différentes avec l'opérateur d'affectation. Dans certains, c'est une déclaration, pas une expression, donc ne peut pas être combinée dans une expression plus grande. Dans certains, il renvoie la valeur assignée, mais seulement comme une valeur (souvent appelée une valeur), et non comme quelque chose qui peut être lui-même modifié ou assigné (une valeur lvalue).Un exemple de ceci est C, où vous pouvez écrire :

a = b = c; # assign value of c to b and a 

mais pas:

++(b = a); # assign value of a to b, then increment b 

Et dans certains cas, le résultat d'une cession est le lvalue affecté. (En Perl, ceci s'applique seulement aux assignations scalaires, les assignations de liste sont une bête plus complexe.) Donc vous pouvez faire ++ ($ b = $ a) ou ($ b = $ a) = ~ s/a/b/ou toute autre opération qui attend une valeur sur l'assignation, et elle fera d'abord l'affectation, puis modifiera la valeur assignée.

+0

Merci, il est bon de savoir que la syntaxe de l'exemple, bien que pas magique, est Perl-spécifique. –

1

Si au T2 vous dire prendre une sous-chaîne à partir de $ a, vous trouverez peut-être cet idiome utile:

($b) = $a =~ /(substring-to-match)/; 
$b =~ s/regex-on-susbtring/result-string/; 

font également remarquer que $ et $ b ne sont pas des variables normales en Perl, car ils avoir des règles de portée spéciales liées à la fonction de tri. Voir 'perldoc perlvar' pour plus de détails.

Questions connexes