在Perl的正则表达式匹配中,是否可以知道{n,}中匹配的数量?

时间:2013-06-26 09:52:04

标签: regex perl match

我的意思是:

例如,a{3,}将贪婪地匹配'a'至少三次。它可能会找到五次,十次等等。我需要这个号码。我需要这个数字用于代码的其余部分。

我可以在不知情的情况下更有效地完成剩下的工作,但我想也许Perl有一些内置变量可以给出这个数字,还是有一些技巧可以得到它?

4 个答案:

答案 0 :(得分:2)

使用@LAST_MATCH_END and @LAST_MATCH_START

my $str = 'jlkjmkaaaaaamlmk';
$str =~ /a{3,}/;
say $+[0]-$-[0];

<强>输出:

6

注意:这只适用于单字符模式。

答案 1 :(得分:2)

抓住它并使用length

if (/(a{3,})/) {
   print length($1), "\n";
}

答案 2 :(得分:0)

如果您的模式/AB{n,}/ A B 是复杂模式,我们可以将正则表达式分成多个部分:

my $string = "ABABBBB";
my $n = 3;

my $count = 0;
TRY:
while ($string =~ /A/gc) {
  my $pos = pos $string; # remember position for manual backtracking
  $count++ while $string =~ /\GB/g;
  if ($count < $n) {
    $count = 0;
    pos($string) = $pos; # restore previous position
  } else {
    last TRY;
  }
}
say $count;

输出:4

但是,将代码嵌入正则表达式进行计数可能更为可取,因为它更为通用:

my $string = "ABABBBB";
my $count;
$string =~ /A(?{ $count = 0 })(?:B(?{ $count++ })){3,}/ and say $count;

输出:4

缺点是此代码不会在较旧的perls上运行。 (代码在v14&amp; v16上进行了测试)。


修改:如果B模式回溯,则第一个解决方案将失败,例如$B = qr/BB?/。该模式应该与ABABBBB字符串匹配三次,但策略只会让它匹配两次。使用嵌入式代码的解决方案允许适当的回溯。

答案 3 :(得分:0)

这是一个想法(也许这就是你已经拥有的?)假设你对计数感兴趣的模式有多个字符和可变长度:

  • 捕获与pattern{3,}子模式匹配的子字符串
  • 然后将捕获的子字符串全局匹配pattern(注意缺少量词),并强制=~上的列表上下文以获取匹配数。

下面是一个示例代码来说明这一点(其中$patt是您想要计算的子模式)

my $str = "some catbratmatrattatblat thing";
my $patt = qr/b?.at/; 

if ($str =~ /some ((?:$patt){3,}) thing/) {
    my $count = () = $1 =~ /$patt/g;
    print $count;
    ...
}

具有2个子图案的另一个(公认有点微不足道)的例子

my $str = "some catbratmatrattatblat thing 11,33,446,70900,";
my $patt1 = qr/b?.at/; 
my $patt2 = qr/\d+,/;

if ($str =~ /some ((?:$patt1){3,}) thing ((?:$patt2){2,})/) {
    my ($substr1, $substr2) = ($1, $2);
    my $count1 = () = $substr1 =~ /$patt1/g;
    my $count2 = () = $substr2 =~ /$patt2/g;
    say "count1: " . $count1;
    say "count2: " . $count2;
}

这种方法的局限性:

看起来很糟糕。请参阅amon's example