2014-09-02 66 views
0

我想從單行字符串$ a1分開得到N + 1個零件,其中$ a1的第一部分包含字符,可能包含數字,逗號,單個空格或連續多個空間。 而part2到partN + 1只包含數字。perl得到最後N次匹配的行內

#  (part1)      (part2) (part3) (part4) 
my $a1=' adf baifdhi ads 1882, 3 123  456  7'; 

$a1 =~ /^(.*)(\s+\d+){$N}$/; 
$part1 = $1; (no problem here) 

但是我怎樣才能得到PartN的partN號碼?看起來2美元只給了我最後一次的比賽。 謝謝

回答

2

重複(...){5}捕獲組將只返回最後一個值。

要獲得所有的值,使用捕獲組周圍反覆表達((?:...){5}),然後split

use strict; 
use warnings; 

#  (part1)      (part2) (part3) (part4) 
my $a1 = ' adf baifdhi ads 1882, 3 123  456  7'; 
my $N = 3; 

if ($a1 =~ /^(.*)((?:\s+\d+){$N})$/) { 
    my $part1 = $1; 
    my @numbers = split ' ', $2; 

    use Data::Dump; 
    dd $part1; 
    dd @numbers; 
} 

輸出:

" adf baifdhi ads 1882, 3 " 
(123, 456, 7) 
1

如果你想分裂出去的領域結束只包含十進制數字,那麼你可以使用split做到這一切。像這樣

use strict; 
use warnings; 
use 5.010; 

my $a1 = ' adf baifdhi ads 1882, 3 123  456  7'; 

my @fields = split /\s+(?=[\d\s]+\z)/, $a1; 

print "$_\n" for @fields; 

輸出

adf baifdhi ads 1882, 
3 
123 
456 
7 
0

需要注意的是,如果你在一個捕獲組使用多個比賽,你只捕獲和捕獲最後一次迭代。

^(.*)(\s+\d+){3}$實施例的第二組caputure將' 7'

Demo

通知在Regex101注:

注:重複捕獲組只捕獲最後一次迭代。 把捕獲組周圍的重複組來捕獲所有 迭代或使用非捕獲組,而不是如果你不 感興趣的數據

如果現在就把^(.*)((?:\s+\d+){3})$此修改您捕捉" 123 456 7"如通過將重複的圖案在非捕獲組(?:\s+\d+){3},然後把該整個組成((?:\s+\d+){3})

Demo

捕獲組的所述第二捕獲組

所以,你的代碼是幾乎權:

use Data::Dump; 

#  (part1)      (part2) (part3) (part4) 
my $a1=' adf baifdhi ads 1882, 3 123  456  7'; 
my $N=3; 

$a1 =~ /^(.*)((?:\s+\d+){$N})$/; 

dd $1; 
# " adf baifdhi ads 1882, 3 " 
dd $2; 
# " 123  456  7" 

您也可以拆分兩個部分:

my ($first, $second)=(split /^(.*)((?:\s+\d+){$N})$/, $a1)[-2,-1]; 

if ($first && $second){ 
    print "$first\n$second"; 
}