Perl regex to capture a repeating group

I want a regex that matches something at the beginning of a line and then matches (and returns) all the other words. For example, given this line:

$line = "one two three etc";

      

I need something like this (it doesn't work):

@matches= $line=~ /^one(?:\s+(\S+))$/;

      

to go back to @matches, the words "two", "three", "etc.".

I don't want to know how to get words. I want to do this with regex. It seems so simple, but I couldn't find a solution.

+3


source to share


4 answers


You cannot have an unknown number of capture groups. If you try to repeat the capture group, the last instance will override the contents of the capture group:

Or:




I suggest either grabbing the whole group and then splitting the spaces:

Or you can do a global match and use \G

and \K

:

+2


source


^.*?\s\K|(\w+)

      

Try it. Check out the demo.



http://regex101.com/r/lS5tT3/2

+1


source


To do this, you need to use an anchor \G

that matches the position at the end of the last match. When you create a template with this anchor, you can get continuous results:

@matches = $line =~ /(?:\G(?!\A)|^one) (\S+)/g; 

      

0


source


The simplest solution is probably split

after the fact:

use strict;
use warnings;

my $line = "one two three etc";

my @matches = $line =~ /^one\s+(.*)/ ? split(' ', $1) : ();

use Data::Dump;
dd @matches;

      

Outputs:

("two", "three", "etc")

      

However, it can also be used \G

to continue from where the previous match was left, and therefore find all non-null spaces using the modifier /g

.

The only trick is to not match \G

at the beginning of the line, so the word one

must match:

my @matches = $line =~ /(?:^one|(?<!\A)\G)\s+(\S+)/g;

      

0


source







All Articles