Reputation: 116169
I have text in the form:
Name=Value1
Name=Value2
Name=Value3
Using Perl, I would like to match /Name=(.+?)/
every time it appears and extract the (.+?) and push it onto an array. I know I can use $1
to get the text I need and I can use =~
to perform the regex matching, but I don't know how to get all matches.
Upvotes: 28
Views: 58443
Reputation: 22560
Instead of using a regular expression you might prefer trying a grammar engine like:
I've given a snippet of a Parse::ResDescent answer before on SO. However Regexp::Grammars looks very interesting and is influenced by Perl6 rules & grammars.
So I thought I'd have a crack at Regexp::Grammars ;-)
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";
}
The above code outputs Value1 Value2 Value3
.
Very nice! The only caveat is that it requires Perl 5.10 and that it may be overkill for the example you provided ;-)
/I3az/
Upvotes: 1
Reputation: 51
The following will give all the matches to the regex in an array.
push (@matches,$&) while($string =~ /=(.+)$/g );
Upvotes: 5
Reputation: 132812
Use a Config::
module to read configuration data. For something simple like that, I might reach for ConfigReader::Simple. It's nice to stay out of the weeds whenever you can.
Upvotes: 1
Reputation: 3236
my @values;
while(<DATA>){
chomp;
push @values, /Name=(.+?)$/;
}
print join " " => @values,"\n";
__DATA__
Name=Value1
Name=Value2
Name=Value3
Upvotes: 9
Reputation: 118128
A m//g
in list context returns all the captured matches.
#!/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";
However, it looks like you are parsing an INI style configuration file. In that case, I will recommend Config::Std.
Upvotes: 55