Ben Morrow <> wrote in message news:<bnoo6h$hr4$>...
> From perldoc perlop:
>
> | The position after the last match can be read or set using the pos()
> | function; see "pos" in perlfunc.
I shoulda thought of that. Thanks.
> /Nota bene/ that you call pos on $str, not $pat.
>
> > Incidentally, the best way to get the $nth match of $pat in $str is
> > $str =~ /(?:.*?($pat)){$n}/;
> > but I'm still curious about short-circuited global matches.
>
> I would have said a better way would be
> $nthmatch = ($str =~ /($pat)/g)[$n];
> , not least because it actually works, but maybe that's just me...
What makes you think that my pattern doesn't work? It does, while
yours actually doesn't: you need to index $n-1 unless you've reset $[
to 1. The difference is that yours does about twice the work, and so
takes about twice as long. The aborting for loop is even slower.
Some benchmark code for your amusement:
#!perl
use strict;
use warnings;
use Benchmark;
my $str='abcabbcabbbbcabcabbcab';
my $n = 3; ## Find the $nth occurrence
my $pat = qr/ab+/; ## of this pattern
sub pat_n;
sub for_g;
sub m_g;
print "pat_n Match $n in $str is ", pat_n, "\n";
print "for_g Match $n in $str is ", for_g, "\n";
print "m_g Match $n in $str is ", m_g, "\n";
timethese( 100_000, {
'$pat{$n}' => \&pat_n,
'for //g' => \&for_g,
'm_g' => \&m_g,
});
sub pat_n {
$str =~ /(?:.*?($pat)){$n}/;
}
sub for_g {
my $NthMatch;
for (1..$n) {
$str =~ /($pat)/g;
$NthMatch = $1;
}
pos($str) = 0;
$NthMatch;
}
sub m_g {
($str =~ /($pat)/g)[$n-1];
}