Вот один из способов. Это требует обновления внешнего счетчика в RE с использованием блока (?{code})
внутри конструкции (?(condition)true-sub-expression|false-sub-expression)
. См. perldoc perlre для объяснения.
use Modern::Perl;
use re qw/eval/; # Considered experimental.
my $string = 'Hello world!';
my $count = 2;
my $re = qr/
(l)
(?(?{$count--})|(*FAIL))
/x;
say "Looking for $count instances of 'l' in $string.";
my ( @found ) = $string =~ m/$re/g;
say "Found ", scalar @found, " instances of 'l': @found";
Вывод:
Looking for 2 instances of 'l' in Hello world!
Found 2 instances of 'l': l l
Вот еще один тест того же регулярного выражения, но на этот раз мы отслеживаем положение совпадений, чтобы доказать, что оно соответствует первым двум вхождениям.
use Modern::Perl;
use strict;
use warnings;
use re qw/eval/; # Considered experimental.
my $string = 'Hello world!';
my $count = 2;
my $position = 0;
my $re = qr/
(l)(?{$position=pos})
(?(?{$count--})|(*FAIL))
/x;
while( $string =~ m/$re/g ) {
say "Found $1 at ", $position;
}
И на этот раз вывод:
Found l at 3
Found l at 4
Не думаю, что я бы порекомендовал что-либо из этого. Если бы я думал об ограничении совпадений только одной частью строки, я бы сопоставил ее с substr()
строки. Но если вам нравится жить на краю, продолжайте и повеселитесь с этим фрагментом.
Вот оно в подстановке:
use Modern::Perl;
use strict;
use warnings;
use re qw/eval/; # Considered experimental.
my $string = 'Hello world!';
say "Before substitution $string";
my $count = 2;
my $re = qr/
(l)
(?(?{$count--})|(*FAIL))
/x;
$string =~ s/$re/L/g;
say "After substitution $string";
И вывод:
Before substitution Hello world!
After substitution HeLLo world!