Please help with regexp - finding all matches?

B

Boris Pelakh

I'm trying to extract name:value pairs from a string similar to this one

{a:b,c:d,e:f}

The individual pieces are more complicated, but its similar in principal

Here is a test script I use

$f = "a:b,c:d,e:f";
@a = ($f =~ m/(?:(\w+):(\w+))(?:,(?:(\w+):(\w+)))+/);
print "@a\n";

I should be seeing "a b c d e f", but I am only getting "a b e f",
i.e. the first and last group matched. Why am I not seeing the rest?
Ideally I want to just assign the result of the match to a hash.

-- Boris
 
J

Jürgen Exner

Boris said:
Here is a test script I use

$f = "a:b,c:d,e:f";
@a = ($f =~ m/(?:(\w+):(\w+))(?:,(?:(\w+):(\w+)))+/);
print "@a\n";

I should be seeing "a b c d e f", but I am only getting "a b e f",

What about a simple

use strict;
use warnings;
my $f = "a:b,c:d,e:f";
my @a;
for (split /,/, $f) {
push @a ,(split /:/);
}
print "@a\n";

In my opinion much easier to write and to read than a complicated RE.

jue
 
J

Jim Gibson

Boris said:
I'm trying to extract name:value pairs from a string similar to this one

{a:b,c:d,e:f}

The individual pieces are more complicated, but its similar in principal

Here is a test script I use

$f = "a:b,c:d,e:f";
@a = ($f =~ m/(?:(\w+):(\w+))(?:,(?:(\w+):(\w+)))+/);
print "@a\n";

I should be seeing "a b c d e f", but I am only getting "a b e f",
i.e. the first and last group matched. Why am I not seeing the rest?
You only see "a b e f" in your output because you only have 4 capturing
parentheses in your pattern, and you only apply your pattern once. The
entire string is matched due to the '+' after the second subgrouping,
but the capturing bits in this group are applied twice: first to
capture the 'c' and the 'd', and then to match and capture the 'e' and
the 'f', overwriting the 'c' and 'd'.

If you want all of the matching bits, use a simpler pattern but use it
repeatedly with the 'g' modifier:

my @a = ( $f =~ m/(?:(\w+):(\w+))/g );

but, as Jürgen pointed out, using split twice is simpler.
Ideally I want to just assign the result of the match to a hash.

Well, then, assign the results of the match to a hash:

my %h = ( $f =~ m/(?:(\w+):(\w+))/g );

FYI: this newsgroup is defunct. Try comp.lang.perl.misc in the future.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top