How to save regex capture in an array in Perl?

I am trying to use regex in Perl. I was wondering if it is possible to save all matches with an expression into an array? I know that I can use the following: ($1,...,$n) = m/expr/g; but it seems you can only use it if you know the number of matches you are looking for. I tried my @array = m/expr/g; but it does not work.

Thanks for your help!

+60
arrays regex perl
Feb 21 '10 at 2:56
source share
5 answers

If you perform a global match ( /g ), then the context in the regular expression returns a list of all captured matches. Just do:

 my @matches = ( $str =~ /pa(tt)ern/g ) 

This command, for example:

 perl -le '@m = ( "foo12gfd2bgbg654" =~ /(\d+)/g ); print for @m' 

Gives output:

 12 2 654 
+74
Feb 21 '10 at 3:17
source share

See the perldoc perlop user guide in the section "Negotiating in a List Context":

If the / g option is not used, m // in the context of the list returns a list consisting of subexpressions matched by parentheses in the template, i.e. ($ 1, $ 2, $ 3 ...)

The / g modifier defines a global pattern matching, i.e. a match as many times as possible within a line. How he behaves depends on the context. In the context of a list, this returns a list of substrings matching any parentheses in the regular expression. If there are no parentheses, it returns a list of all matching lines, as if there were parentheses around the entire pattern.

You can simply capture all matches by assigning an array, or else doing an assessment in the context of the list:

 my @matches = ($string =~ m/word/g); 
+17
Feb 21 2018-10-21T00
source share

Sometimes you need to get all the matches around the world, as PHP preg_match_all does. If this is your case, then you can write something like:

 # a dummy example my $subject = 'Philip Fry Bender Rodriguez Turanga Leela'; my @matches; push @matches, [$1, $2] while $subject =~ /(\w+) (\w+)/g; use Data::Dumper; print Dumper(\@matches); 

He is typing

 $VAR1 = [ [ 'Philip', 'Fry' ], [ 'Bender', 'Rodriguez' ], [ 'Turanga', 'Leela' ] ]; 
+17
Feb 21 '10 at 9:46
source share

I think this is an explanatory example. Note that the /g modifier in the first regular expression:

 $string = "one two three four"; @res = $string =~ m/(\w+)/g; print Dumper(@res); # @res = ("one", "two", "three", "four") @res = $string =~ m/(\w+) (\w+)/; print Dumper(@res); # @res = ("one", "two") 

Remember that you need to make sure that the lvalue value is in the context of the list, which means that you must surround the scalar values ​​with brackets:

 ($one, $two) = $string =~ m/(\w+) (\w+)/; 
+8
Dec 11 '12 at 19:12
source share

Please note that if you know the number of capture groups that you need per match, you can use this simple approach, which I present as an example (from 2 capture groups).

Suppose you have some data

 my $mess = <<'IS_YOURS'; Richard Rich April May Harmony Ha\rm Winter Win Faith Hope William Will Aurora Dawn Joy IS_YOURS 

With the following regex

 my $oven = qr'^(\w+)\h+(\w+)$'ma; # skip the /a modifier if using perl < 5.14 

I can capture all 12 (6 pairs, not 8 ... Harmony escaped and Joey is missing) in @box below.

 my @box = $mess =~ m[$oven]g; 

If I want to β€œparse” the box details, I could just do:

 my %hash = @box; 

Or I could just skip the box completely,

 my %hash = $mess =~ m[$oven]g; 

Note that %hash contains the following. The order is lost, and duplicate keys (if any) were squeezed:

 ( 'April' => 'May', 'Richard' => 'Rich', 'Winter' => 'Win', 'William' => 'Will', 'Faith' => 'Hope', 'Aurora' => 'Dawn' ); 
0
May 28 '19 at 6:30 a.m.
source share



All Articles