2010-09-06 9 views
37

Je souhaite être en mesure d'effectuer une correspondance regex sur une variable et affecter les résultats à la variable elle-même. Quelle est la meilleure façon de le faire?Correspondre à une expression régulière et affecter des résultats à une seule ligne de code

Je veux essentiellement combiner les lignes 2 et 3 en une seule ligne de code:

$variable = "some string"; 
$variable =~ /(find something).*/; 
$variable = $1; 

est-il un moyen plus court/plus simple de le faire? Est-ce que je manque quelque chose?

Répondre

24

Pourquoi voulez-vous qu'il soit plus court? Est-ce que c'est vraiment important?

$variable = $1 if $variable =~ /(find something).*/; 

Si vous êtes inquiet au sujet du nom de la variable ou de faire cela à plusieurs reprises, envelopper la chose dans un sous-programme et de l'oublier:

some_sub($variable, qr/pattern/); 
sub some_sub { $_[0] = $1 if eval { $_[0] =~ m/$_[1]/ }; $1 }; 

Cependant, vous le mettre en œuvre, le point du sous-programme est de Faites en sorte qu'il soit réutilisable pour que vous donniez à un ensemble particulier de lignes un nom court qui se trouve à leur place.

7

Vous pouvez le faire en tant que substitution:

$a = 'stackoverflow'; 
$a =~ s/(\w+)overflow/$1/; 

$a est maintenant "stack"

+0

Il y a un problème avec ceci, il ne remplacera la variable d'origine que si la chaîne entière est présente dans le motif de recherche. Si je devais utiliser, disons,/(\ w +) sur/pour l'appariement, cela ne fonctionnerait pas. –

+0

Le motif est arbitraire, les correspondances ne commencent pas nécessairement à une limite de ligne ou de mot. En tout cas, merci, je suppose qu'il n'y a pas de façon évidemment simple de le faire. Ma principale préoccupation était que je devais le faire souvent, et cela semble répétitif. –

+0

J'ai trébuché sur ce fil de 2 ans via Google, et je pense que c'est la bonne réponse. Il suffit de modifier l'expression rationnelle pour répondre à vos besoins: /.*(find quelque chose). */$ 1 /; – Mintx

4

Presque ....

Vous pouvez combiner le match et récupérer la valeur assortie d'une substitution. AFAIK, vous devrez toujours copier la valeur, sauf si vous ne voulez pas écraser l'original.

6

Eh bien, vous pourriez dire

my $variable; 
($variable) = ($variable = "find something soon") =~ /(find something).*/; 

ou

(my $variable = "find something soon") =~ s/^.*?(find something).*/$1/; 
+0

Je préfère utiliser la définition de variable séparément pour des raisons de clarté, mais oui c'est une bonne solution pour les recherches rapides. Merci. –

3

Je fais ceci:

#!/usr/bin/perl 

$target = "n: 123"; 
my ($target) = $target =~ /n:\s*(\d+)/g; 
print $target; # the var $target now is "123" 
52
my($variable) = "some string" =~ /(e\s*str)/; 

Cela fonctionne parce que

Si l'option /g est pas utilisée, m// dans un contexte de liste retourne une liste constituée par les sous-expressions reconnus par des parenthèses dans le motif, à savoir , ($1, $2, $3 ...).

et parce que my($variable) = ... (notez les parenthèses autour du scalaire) fournit un contexte de liste pour le match.

Si le motif ne correspond pas, $variable obtient la valeur indéfinie.

+0

Ajouter à la description dans le contexte de la liste. Le OoO est équivalent à 'my ($ foo) = (" bar box "= ~/(soap | box) /);' – vol7ron

+0

Je vais aussi ajouter un autre exemple. Si vous voulez ajouter une chaîne aux résultats dans le même appel: 'my ($ foo) = map (" préfixe _ $ _ ", @ {[" bar box "= ~/(soap | box) /)]}) ". Vous finiriez avec "prefix_box" dans ce cas. – vol7ron

+2

Cela devrait être la réponse acceptée! – mrfred

4
$variable2 = "stackoverflow"; 
(my $variable1) = ($variable2 =~ /stack(\w+)/); 

$variable1 est maintenant égal à "overflow".

Questions connexes