簡體   English   中英

如何在 Perl 中匹配正則表達式單組合與多組相同模式

[英]How to match regex single combine with multi groups same pattern in Perl

我有以下格式的數據:

n123a456ba789ba101112ba131415b
n124a12345ba78910ba101113b
n125a1234ba7891ba101114ba131415ba16171819b

n 跟隨一些數據直到 a。

a 是起始字段。

b 是結束字段。

它有多個字段 a...b

我想將 a...b 之間的 n 個數據和數據捕獲到數組中。 我嘗試使用以下代碼但沒有用。

$var = "n123a456ba789ba101112ba131415b";

($n, @groups) = $var =~ /n(.+?)(?:a(.+?)b)+/;

print join(',', $n, @groups);

您可以使用以下正則表達式:

請參閱此處使用的正則表達式

/(?|n([^a]+)(?=a)|a([^b]+)b)/g

這個怎么運作:

  • (?|...)分支重置 - 這樣一個組中的任何子模式共享相同的編號(如果存在交替,這使得捕獲組共享相同的索引)
  • n([^a]+)(?=a)|a([^b]+)b匹配以下任一選項:
    • n([^a]+)(?=a)
      • n比賽n字面上
      • ([^a]+)將除a以外a任何字符捕獲到一個捕獲組中
      • (?=a)確保字符a跟隨(正向前瞻)而不消耗字符
    • a([^b]+)b
      • a匹配a字面上
      • ([^b]+)捕獲除b以外的任何字符一次或多次進入捕獲組
      • b匹配b字面上

在此處查看正在使用的代碼

$var = "n123a456ba789ba101112ba131415b";
($n, @groups) = $var =~ /(?|n([^a]+)(?=a)|a([^b]+)b)/g;
print join(',', $n, @groups);

目標樣本線似乎相當一致。
這是在單個數組中獲取所有內容的快速方法,或者如果需要my ($n, @vals)可以通過my ($n, @vals)

$_ = "n123a456ba789ba101112ba131415b";
my @vals = /[na]([^ab]*)/g;
print join(',', @vals)

輸出

123,456,789,101112,131415

請驗證以下代碼是否符合您的要求

use strict;
use warnings;

use feature 'say';

use Data::Dumper;

my %hash;

while( <DATA> ) {
    if( /^n(\d+)/ ) {
        my $n = $1;
        my @data = /a(\d+?)b/g;
        $hash{$n} = \@data;
    } 
}

say Dumper(\%hash);

__DATA__
n123a456ba789ba101112ba131415b
n124a12345ba78910ba101113b
n125a1234ba7891ba101114ba131415ba16171819b

輸出

$VAR1 = {
          '123' => [
                     '456',
                     '789',
                     '101112',
                     '131415'
                   ],
          '125' => [
                     '1234',
                     '7891',
                     '101114',
                     '131415',
                     '16171819'
                   ],
          '124' => [
                     '12345',
                     '78910',
                     '101113'
                   ]
        };

另一種方法是使用split

use strict;
use warnings;
use Data::Dump qw(dump);

while(<DATA>) {
    chomp;
    my @l = split /[nab]+/, $_;
    shift @l;
    dump@l;
}

__DATA__
n123a456ba789ba101112ba131415b
n124a12345ba78910ba101113b
n125a1234ba7891ba101114ba131415ba16171819b

輸出:

(123, 456, 789, 101112, 131415)
(124, 12345, 78910, 101113)
(125, 1234, 7891, 101114, 131415, 16171819)

暫無
暫無

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

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