Finding the Nth Occurrence of a Match
Problem
You want to find the N
th match in a string, not just
the first one. For example, you’d like to find the word
preceding the third occurrence of "fish":
One fish two fish red fish blue fishSolution
Use the /g
modifier in a
while loop, keeping count of matches:
$WANT = 3;
$count = 0;
while (/(\w+)\s+fish\b/gi) {
if (++$count == $WANT) {
print "The third fish is a $1 one.\n";
# Warning: don't `last' out of this loop
}
}
The third fish is a red one.Or use a repetition count and repeated pattern like this:
/(?:\w+\s+fish\s+){2}(\w+)\s+fish/i;Discussion
As explained in the chapter introduction, using the
/g modifier in scalar context creates something of
a
progressive
match, useful in while loops. This is
commonly used to count the number of times a pattern matches in a
string:
# simple way with while loop
$count = 0;
while ($string =~ /PAT/g) {
$count++; # or whatever you'd like to do here
}
# same thing with trailing while
$count = 0;
$count++ while $string =~ /PAT/g;
# or with for loop
for ($count = 0; $string =~ /PAT/g; $count++) { }
# Similar, but this time count overlapping matches
$count++ while $string =~ /(?=PAT)/g;To find the Nth match, it’s easiest
to keep your own counter. When you reach the appropriate N, do
whatever you care to. A similar technique could be used to find every
Nth match by checking for multiples of N
using the modulus operator. For example, (++$count
%
3)
==
0 would be every third match.
If this is too much bother, ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access