2014-09-02 1 views
0

Я хочу получить N + 1 части отдельно от одной строки строки $ a1, где первая часть $ a1 содержит символы, может содержать цифры, запятую, однократное или последовательное несколько пространств. , а для частей 2 - часть N + 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) 

Но как я могу получить номера для part2 partN? Кажется, 2 доллара дает мне только последнюю встречу матча. Thanks

ответ

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"; 
} 
Смежные вопросы