Reputation: 51
I'm trying to match an array of elements preceeded by a specific string in a line of text. For Example, match all pets in the text below:
fruits:apple,banana;pets:cat,dog,bird;colors:green,blue
/(?:pets:)(\w+[,|;])+/g**
Using the given regex I only could match the last word "bird"
Can anybody help me to understand the right way of using Non-Capturing and Capturing Groups?
Thanks!
Upvotes: 3
Views: 22826
Reputation: 18950
Since you want to have each pet in a separate match and you are using PCRE \G
is, as suggested by Wiktor, a decent option:
(?:pets:)|\G(?!^)(\w+)(?:[,;]|$)
Explanation:
(?:pets:)
to find the start of the pattern\G(?!^)(\w+)(?:[,;]|$)
\G
asserts position at the end of the previous match or the start of the string for the first match (\w+)
to matches the pets(?:[,;]|$)
used as a delimiter (matches a single character in the list ,;
(case sensitive) or $
asserts position at the end of the stringPerl Code Sample:
use strict;
use Data::Dumper;
my $str = 'fruits:apple,banana;pets:cat,dog,bird;colors:green,blue';
my $regex = qr/(?:pets:)|\G(?!^)(\w+)(?:[,;]|$)/mp;
my @result = ();
while ( $str =~ /$regex/g ) {
if ($1 ne '') {
#print "$1\n";
push @result, $1;
}
}
print Dumper(\@result);
Upvotes: 3
Reputation: 131
First, let's talk about capturing and non-capturing group:
So:
(?:pets:) you searching for "pets" but don't want to capture it, after that point, you WANT to capture (if I've understood):
So try (?:pets:)([a-zA-Z,]+); ... You're searching for "pets:" (but don't want it !) and stop at the first ";" (and don't want it too).
Result is : Match 1 : cat,dog,bird
A better solution exists with 1 match == 1 pet.
Upvotes: 7