2009-11-12 19 views
17

tengo el texto en la forma:¿Cómo puedo encontrar todas las coincidencias con una expresión regular en Perl?

Name=Value1 
Name=Value2 
Name=Value3 

Utilizando Perl, me gustaría coincidir /Name=(.+?)/ cada vez que aparece y extraer el y empujarlo hacia una matriz (+.?). Sé que puedo usar $1 para obtener el texto que necesito y puedo usar =~ para realizar la comparación de expresiones regulares, pero no sé cómo obtener todas las coincidencias.

+0

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

Respuesta

41

A m//g en la lista context devuelve todas las coincidencias capturadas.

#!/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"; 

Sin embargo, parece que está analizando un archivo de configuración de estilo INI. En ese caso, recomendaré Config::Std.

+5

El importante Lo que hay que notar es la 'g' al final de la expresión regular. – mob

+0

En realidad, simplifiqué el formato. Hay texto en el medio, pero hasta que maneje el caso simple, no había ninguna esperanza de que manejara el caso más grande. –

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

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

No use $ 1 si la expresión regular no tuvo éxito: '/Name=(.+?)$/ y push @values, $ 1'. O incluso simplemente 'mis @ valores = map /Name=(.+?)$/, ;' – ysth

0

En lugar de utilizar una expresión regular es posible que prefiera probar un motor de la gramática como:

me he dado un fragmento de una respuesta antes de Parse::ResDescent en lo. Sin embargo, Regexp :: Grammars se ve muy interesante y está influenciado por Perl6 rules & grammars.

Así que pensé que tendría una grieta en Regexp :: Gramáticas ;-)

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"; 
} 

Las salidas de código anteriores Value1 Value2 Value3.

¡Muy bonito! La única salvedad es que requiere Perl 5.10 y que puede ser excesiva para el ejemplo que ya ha proporcionado ;-)

/I3az/

1

uso de un módulo Config:: para leer los datos de configuración. Para algo simple como eso, podría alcanzar el ConfigReader::Simple. Es bueno mantenerse alejado de las malas hierbas siempre que sea posible.

3

Lo siguiente dará todas las coincidencias con la expresión regular en una matriz.

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