Akshay Belvadi
Akshay Belvadi

Reputation: 31

Matching repetition with capturing groups returns only the final match value

I am trying to capture a recursive sequence using matching repetition with capturing groups.

Here is a sample text:

some_string_here  00  12.34  34  56.78  78.90

The regexp used to capture all the floating point values:

\S+(?:\s+(\d+(?:\.\d+)?)){5}

The regexp matches all the floating point values as expected but the capturing group returns only the final match result.

Group #1: 78.90

The required result is:

Group #1: 00
Group #2: 12.34
Group #3: 34
Group #4: 56.78
Group #5: 78.90

If I use the following as the regexp, the result is as expected, but with too many recursive sequence, the regexp is too long.

\S+(?:\s+(\d+(?:\.\d+)?))(?:\s+(\d+(?:\.\d+)?))(?:\s+(\d+(?:\.\d+)?))(?:\s+(\d+(?:\.\d+)?))(?:\s+(\d+(?:\.\d+)?))

Is there a way to capture all of the floating point values in a matching repetition with capturing groups?

Upvotes: 3

Views: 147

Answers (3)

Borodin
Borodin

Reputation: 126722

As I mentioned in my comment, you probably just want split, like this

my $s = 'some_string_here  00  12.34  34  56.78  78.90';

my @groups = split ' ', $s;
shift @groups;

for my $i ( 0 .. $#groups ) {
    printf "Group #%d: %-s\n", $i+1, $groups[$i];
}

output

Group #1: 00
Group #2: 12.34
Group #3: 34
Group #4: 56.78
Group #5: 78.90

Upvotes: 1

mkHun
mkHun

Reputation: 5927

Try this

$s = "some_string_here  00  12.34  34  56.78  78.90";
@ar = $s =~m/(\d+\.?(?:\d+)?)/g;
$, = "\n";
print @ar;

g flag returns all possible matches in a list. And the list was stored into the array. So it will give the all possible matches in an array.

Without using g global modifier it returns the only one element that is 00. Because search will satisfy at a first match.

output

00
12.34
34 
56.78
78.90

Else you want to store particular number of elements, create the list and the give the variables

For example, you want to store the only three matches,

($first,$second,$thrid) = $s =~m/(\d+\.?(?:\d+)?)/g;

Here $first holds the 00, $second holds the 12.34 and the $third holds the 34.

Upvotes: 1

Tim007
Tim007

Reputation: 2557

Try this

(\d+\.?\d*)

Demo

Input

some_string_here  00  12.34  34  56.78  78.90

Output

MATCH 1
1.  [18-20] `00`
MATCH 2
1.  [22-27] `12.34`
MATCH 3
1.  [29-31] `34`
MATCH 4
1.  [33-38] `56.78`
MATCH 5
1.  [40-45] `78.90`

Upvotes: 0

Related Questions