Ваш разделитель записей должен быть "\n\n"
. Каждая строка заканчивается одним, и вы дифференцируете блок по двойной новой строке. Используя эту идею, было довольно легко отфильтровать блоки с помощью свойства 4.
use strict;
use warnings;
use English qw<$RS>;
open( my $inh, ... ) or die "I'm dead!";
local $RS = "\n\n";
while ( my $block = <$inh> ) {
if ( my ( $prop4 ) = $block =~ m/^Property 4:\s+(.*)/m ) {
...
}
if ( my ( $prop3, $prop6 )
= $block =~ m/
^Property \s+ 3: \s+ ([^\n]*)
.*?
^Property \s+ 6: \s+ ([^\n]*)
/smx
) {
...
}
}
Оба выражения используют многострочный ('m') флаг, так что ^
применяется к любому началу строки. Последний использует флаг для включения новых строк в '.' выражения ('s') и расширенный синтаксис ('x'), который, помимо прочего, игнорирует пробелы в выражении.
Если бы данные были довольно маленькими, вы могли бы обработать все это за один раз, как:
use strict;
use warnings;
use English qw<$RS>;
local $RS = "\n\n";
my @block
= map { { m/^Property \s+ (\d+): \s+ (.*?\S) \s+/gmx } } <DATA>
;
print Data::Dumper->Dump( [ \@block ], [ '*block' ] ), "\n";
Который показывает результат:
@block = (
{
'1' => '1234',
'3' => 'ACBGD',
'2' => '34546'
},
{
'4' => '4567',
'1' => '1234'
},
{
'6' => 'example',
'1' => 'just',
'3' => 'an',
'5' => 'simple'
}
);