2015-11-14 4 views
1

Почему этот код:Perl Regex Capture в массив

my $text = "!a!b!c!"; 
my @captures = ($text =~ /!(.)!/g); 
print "$_\n" foreach @captures; 

Только выход

a 
c 

?

Ожидаемый результат:

a 
b 
c 

Как я могу захватить их все?

+2

Используйте lookahead, чтобы не потреблять второй '!': '($ Text = ~ /!(.)(?=!)/ g);'. Однако ваш код выводит 'a' и' c', а не только 'a'. –

+0

Почему бы просто не просто «my @matches = split»! »,«! A! B! C! »;' – hwnd

+0

@hwnd это была лишь абстрактная проблема в попытке лучше понять захваты, но ваш подход тоже полезен – beasy

ответ

2

Вы должны использовать смотреть вперед, чтобы не потреблять второй ! и сохранить его для следующего регулярных выражений итерации:

/!(.)(?=!)/g 

Во-первых, ! подобран, то любой символ, но символ новой строки, что прямо перед !, который не потребляется, индекс двигателя регулярного выражения остается перед ним. Итак, следующий матч может начаться с этого !.

Обновленный код:

my $text = "!a!b!c!"; 
my @captures = ($text =~ /!(.)(?=!)/g); 
print "$_\n" foreach @captures; 

Выход:

a 
b 
c 

Расщепление с ! может оказаться более юбилеи, альтернатива Опубликованная в настоящее время сценария:

my $text = "!a!b!c!"; 
my @matches = grep /\S/, split "!", $text; 
print "$_\n" foreach @matches; 

Обратите внимание, что grep /\S/ будет удалять пустые или простые пробелы из массива полученный с помощью split.