2010-10-23 6 views
3

Existe-t-il un moyen de le faire en une ligne?Rechercher et remplacer sans enregistrer la variable

my $b = &fetch(); 
$b =~ s/find/replace/g; 
&job($b) 
+4

'my $ b = & fetch(); $ b = ~ s/trouver/remplacer/g; & travail ($ b) ' –

+0

Ha! C'est une façon, mais ce n'est pas ce que je voulais dire ... –

+0

une raison pour laquelle vous avez besoin d'utiliser et d'appeler un sous-marin? Utilisez-vous Perl v4? – mfontani

Répondre

4

Bien sûr, avec un bloc do {}:

use strict; 
use warnings; 

sub fetch { 'please find me' } 
sub job { print @_, "\n" } 

job(do { $_ = fetch(); s/find/replace/g; $_ }); 

La raison étant que Perl vous ne pouvez pas faire fetch() =~ s/find/replace/;:
Can't modify non-lvalue subroutine call in substitution (s///) at ...

Perl 5.14 présentera le drapeau /r (ce qui rend l'expression rationnelle retourner la chaîne avec des substitutions plutôt que le nombre de substitutions) et réduira le dessus à:

job(do { $_ = fetch(); s/find/replace/gr; }); 

modifié grâce à FM: peut raccourcir le dessus:

job(map { s/find/replace/g; $_ } fetch()); 

Et une fois que Perl 5.14 sera sur elle peut être raccourcie à:

job(map { s/find/replace/gr } fetch()); 
+0

Upvote pour l'information sur Perl 5.14; C'est pourquoi j'ai lu des réponses à des questions que je crois savoir déjà, parce que parfois vous apprenez encore même quand vous le saviez! Maintenant, si seulement nous pouvions obtenir Ubuntu pour livrer quelque chose de plus récent que 5.10.1. –

+0

http://search.cpan.org/dist/App-perlbrew/lib/App/perlbrew.pm est facile et indolore. Vous ne devriez pas vraiment compter sur le _system_ Perl pour votre code, de toute façon :) – mfontani

+0

toujours localiser les changements à '$ _' –

4

Si vous demandez si vous devez passer par une variable scalaire pour effectuer le remplacement, la réponse est oui. C'est parce que le résultat de la substitution doit être stocké quelque part. De plus, la substitution ne renvoie pas la variable utilisée, elle renvoie le nombre de substitutions effectuées. Par conséquent, vous ne pouvez pas le mettre en ligne (c'est-à-dire le travail & ($ b = ~ s/find/replace/g)) dans l'appel de fonction.

+0

En Java, je peux envoyer le résultat de 'replaceAll (regex)' directement dans le sous-programme de travail. J'espérais que cela pourrait être fait en Perl. Je vais attendre un moment avant d'abandonner. –

+0

GeorgeBailey, l'approche Java nécessitera également un stockage de mémoire intermédiaire du résultat, seulement que c'est dans les coulisses. –

0
for (fetch() . '') { # append with '' to make sure it is a non-constant value 
    s/find/replace/g; 
    job($_) 
} 

ou de l'utilisation apply à partir de l'un des modules Liste:

use List::Gen qw/apply/; 

job(apply {s/find/replace/g} fetch());