web-dev-qa-db-fra.com

Faites correspondre les expressions rationnelles et assignez les résultats dans une seule ligne de code

Je veux être capable de faire une correspondance regex sur une variable et d'assigner les résultats à la variable elle-même. Quelle est la meilleure façon de le faire?

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

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

Existe-t-il un moyen plus simple/plus simple de procéder? Est-ce que je manque quelque chose?

37
user354606

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

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

Si vous êtes inquiet au sujet du nom de la variable ou si vous faites cela à plusieurs reprises, encapsulez-le dans un sous-programme et oubliez-le:

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

Quelle que soit la manière dont vous l'implémentez, l'objectif du sous-programme est de le rendre réutilisable afin de donner à un ensemble de lignes particulier un nom court qui se trouve à leur place.

25
brian d foy
my($variable) = "some string" =~ /(e\s*str)/;

Cela fonctionne parce que 

Si l'option /g n'est pas utilisée, m// dans le contexte de liste renvoie une liste composée des sous-expressions associées aux parenthèses du modèle, i.e. , ($1, $2, $3…).

et parce que my($variable) = ... (notez les parenthèses autour du scalaire) fournit le contexte de liste à la correspondance.

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

55
Greg Bacon

Vous pouvez faire la substitution comme:

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

$a est maintenant "stack"

7
codaddict

Eh bien, vous pourriez dire

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

ou

(my $variable = "find something soon") =~ s/^.*?(find something).*/$1/;
6
Chas. Owens
$variable2 = "stackoverflow";
(my $variable1) = ($variable2 =~ /stack(\w+)/);

$variable1 est maintenant égal à "overflow".

4
Dmitri Lihhatsov

Presque ....

Vous pouvez combiner la correspondance et récupérer la valeur correspondante avec une substitution.

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

Si je comprends bien, vous devrez toujours copier la valeur, à moins que vous ne vouliez pas écraser l’original.

4
Peter Tillemans

Tiré de Perl Cookbook, 2e éd 6.1 Copier et remplacer simultanément

$dst = $src;
$dst =~ s/this/that/;

devient

($dst = $src) =~ s/this/that/;

J'ai juste supposé que tout le monde l'avait fait ainsi, étonné que personne ne donne cette réponse.

3
user3287506

Je fais ça: 

#!/usr/bin/Perl

$target = "n: 123";
my ($target) = $target =~ /n:\s*(\d+)/g;
print $target; # the var $target now is "123"
3
Jet

De même, pour amplifier la réponse acceptée à l'aide de l'opérateur ternaire afin de vous permettre de spécifier une valeur par défaut s'il n'y a pas de correspondance:

my $match = $variable =~ /(*pattern*).*/ ? $1 : *defaultValue*;
0
atrobinson