2009-11-12 7 views
17

Je texte sous la forme:Comment trouver toutes les correspondances avec une expression régulière dans Perl?

Name=Value1 
Name=Value2 
Name=Value3 

En utilisant Perl, je voudrais correspondre /Name=(.+?)/ à chaque fois qu'il apparaît et extraire le et le pousser sur un tableau (+.?). Je sais que je peux utiliser $1 pour obtenir le texte dont j'ai besoin et je peux utiliser =~ pour effectuer la correspondance de regex, mais je ne sais pas comment obtenir toutes les correspondances.

+0

connexes: http://stackoverflow.com/questions/1034027/how-do-i-access-captured-substrings-after-a-successful-regex-match-in-perl –

Répondre

41

Un m//g dans le contexte de liste renvoie toutes les correspondances capturées.

#!/usr/bin/perl 

use strict; use warnings; 

my $str = <<EO_STR; 
Name=Value1 
Name=Value2 
Name=Value3 
EO_STR 

my @matches = $str =~ /=(\w+)/g; 
# or my @matches = $str =~ /=([^\n]+)/g; 
# or my @matches = $str =~ /=(.+)$/mg; 
# depending on what you want to capture 

print "@matches\n"; 

Cependant, il semble que vous analysiez un fichier de configuration de style INI. Dans ce cas, je vais recommander Config::Std.

+5

importants chose à noter est le 'g' à la fin de l'expression régulière. – mob

+0

En fait, j'ai simplifié le format. Il y a du texte au milieu, mais jusqu'à ce que je m'occupe du cas le plus simple, il n'y avait aucun espoir que je traite le cas plus large. –

4
my @values; 
while(<DATA>){ 
    chomp; 
    push @values, /Name=(.+?)$/; 
} 
print join " " => @values,"\n"; 

__DATA__ 
Name=Value1 
Name=Value2 
Name=Value3 
+5

N'utilisez pas $ 1 si la regex n'a pas réussi: '/Name=(.+?)$/ et appuyez sur @values, $ 1'. Ou même juste 'my @values ​​= map /Name=(.+?)$/, ;' – ysth

0

Au lieu d'utiliser une expression régulière, vous préférez peut-être essayer un moteur de grammaire comme:

J'ai donné un extrait d'une Parse::ResDescent réponse avant sur SO. Cependant Regexp :: Grammars semble très intéressant et est influencé par Perl6 rules & grammars.

Je pensais que j'aurais une fissure à Regexp :: Grammaires de

use strict; 
use warnings; 
use 5.010; 

my $text = q{ 
Name=Value1 
Name = Value2 
Name=Value3 
}; 

my $grammar = do { 
    use Regexp::Grammars; 
    qr{ 
     <[VariableDeclare]>* 

     <rule: VariableDeclare> 
      <Var> \= <Value> 

     <token: Var> Name 

     <rule: Value> <MATCH= ([\w]+) > 
    }xms; 
}; 


if ($text =~ $grammar) { 
    my @Name_values = map { $_->{Value} } @{ $/{VariableDeclare} }; 
    say "@Name_values"; 
} 

Les sorties de code ci-dessus Value1 Value2 Value3.

Très bien! La seule mise en garde est qu'il nécessite Perl 5.10 et qu'il peut être surpuissant pour l'exemple que vous avez fourni ;-)

/I3az/

1

Utilisez un module Config:: pour lire les données de configuration. Pour quelque chose de simple comme ça, je pourrais atteindre ConfigReader::Simple. C'est agréable de rester à l'écart des mauvaises herbes quand vous le pouvez.

3

Ce qui suit donnera toutes les correspondances à la regex dans un tableau.

push (@matches,$&) while($string =~ /=(.+)$/g); 
Questions connexes