如上所述,没有内置的。这里有几种方法,使用split、index 和正则表达式。
use warnings;
use strict;
use feature qw(say);
my $str = "Xab_ab_ab_ab_"; # 'Xab_ab'; # test failed (3) matches
my $N = 3;
foreach my $patt qw(a ab c) {
say "Find index of occurrence $N of |$patt| in: |$str|";
say "index: ", ( ind_Nth_match_1($str, $patt, $N) // "no $N matches" ); #/
say "split: ", ( ind_Nth_match_2($str, $patt, $N) // "no $N matches" ); #/
say "regex: ", ( ind_Nth_match_3($str, $patt, $N) // "no $N matches" ); #/
}
sub ind_Nth_match_1 {
my ($str, $patt, $N) = @_;
my ($pos, $cnt) = (0, 0);
while ($pos = index($str, $patt, $pos) + 1) { # != 0
return $pos-1 if ++$cnt == $N;
}
return;
}
sub ind_Nth_match_2 {
my ($str, $patt, $N) = @_;
my @toks = split /($patt)/, $str;
return if @toks < 2*$N;
return length( join '', @toks[0..2*$N-1] ) - length($patt);
}
sub ind_Nth_match_3 {
my ($str, $patt, $N) = @_;
my $cnt = 0;
while ($str =~ m/$patt/g) {
return $-[0] if ++$cnt == $N;
}
}
打印出来
查找 |a| 的出现 3 的索引在:|Xab_ab_ab_ab_|
指数:7
分裂:7
正则表达式:7
查找 |ab| 的出现索引 3在:|Xab_ab_ab_ab_|
指数:7
分裂:7
正则表达式:7
查找 |c| 的出现索引 3在:|Xab_ab_ab_ab_|
索引:没有 3 个匹配项
分裂:没有 3 场比赛
正则表达式:没有 3 个匹配项
注意事项
-
在split 中,每个定界符也会在输出列表中返回,并捕获/($patt)/,以便更简单地估计length。因此我们计算2*$N(然后计算-1)。
-
在正则表达式中,@- array 使用 @LAST_MATCH_START 表示最后一次成功匹配的位置。这里 while 中标量上下文中的 /g 使它在重复执行中从一个匹配跳到下一个匹配,$-[0] 给出最后一个(前一个)这样的匹配的起始位置。
-
如果不需要$N 匹配,则潜艇返回undef,包括根本没有匹配。
感谢Borodin 来自潜艇的return 的cmets 以及使用@- 而不是@+。