簡體   English   中英

在Perl的正則表達式匹配中,是否可以知道a {n,}中的匹配數目?

[英]In regular expression matching of Perl, is it possible to know number of matches in a{n,}?

我的意思是:

例如, a{3,}至少會與“ a”匹配三倍。 它可能找到五次,十次,等等。我需要這個數字。 其余的代碼我需要這個數字。

我可以在不知道的情況下降低其余部分的效率,但是我認為Perl可能有一些內置變量來提供此數字,或者是否有一些技巧來獲取它?

使用@LAST_MATCH_END和@LAST_MATCH_START

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

輸出:

6

注意:這僅適用於一個字符模式。

只需捕獲它並使用length

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

如果您具有類型/AB{n,}/模式,其中AB是復雜模式,我們可以將正則表達式分為多個部分:

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和v16上進行了測試)。


編輯:如果B模式回溯,第一個解決方案將失敗,例如$B = qr/BB?/ 該模式應與ABABBBB字符串匹配3次,但該策略僅使其匹配2次。 使用嵌入式代碼的解決方案允許適當的回溯。

假設您要計數的模式具有多個字符和可變長度,這是一個想法(也許這就是您已經擁有的?):

  • 捕獲與pattern{3,}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的示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM