#! perl -slw use strict; use Data::Dumper; local $/=''; # Paragraph mode my $re = qr/ ^(Name) \s+ : \s > ( [^<]* ) < \s+ \[ ( [^\x5D]* ) \] \s+ # 1, 2, 3 ^(IC) \s+ : \s ' ( [^']* ) ' \s+ \[ ( [^\x5D]* ) \] \s+ # 4, 5, 6 ^(PC) \s+ : \s ( \d* ) \s+ \[ ( [^\x5D]* ) \] \s+ # 7, 8, 9 ^(Number) \s+ : \s > ( [^<]* ) < \s+ \[ ( [^\x5D]* ) \] \s+ # 10, 11, 12 ^(Location) \s+ : \s > ( [^<]* ) < \s+ \[ ( [^\x5D]* ) \] \s+ # 13, 14, 15 ^(extension) \s+ : \s > ( [^<]* ) < \s* # 16, 17 ^(Capability) \s+ : \s > ( [^<]* ) < (?: \s+ \[ ( [^\x5D]* ) \] )? \s* # 18, 19, 20 ^(Info) \s+ : \s > ( [^<]* ) < (?: \s+ \[ ( [^\x5D]* ) \] )? # 21, 22, 23 /mx; my @records; while( ) { my %hash; @hash{$1, $4, $7, $10, $13, $16, $18, $21} = ( [$2, $3], [$5, $6], [$8, $9], [$11, $12], [$14, $15], $17, [$19, $20], [$22, $23], ) if m[$re]; if( %hash ) { push @records, \%hash; } else { warn "Record $.\n'$_'\nfailed to match."; } } print Dumper \@records; __DATA__ Name : >Mick< [Mick] IC : '91919191929' [9191919129] PC : 123 [123] Number : >1960132400000< [1960132400000] Location : >000e 0036< [000e 0036] extension : >< Capability : >"CARES< ["CARES] Info : >6005494c523142< [6005494c523142] Name : >Nick< [Nick] IC : '1235467000' [1235467000] PC : 124 [124] Number : >1960192500000< [1960192500000] Location : >000f 0034< [000f 0034] extension : >< Capability : >< Info : >< Name : >Nick< [Nick] IC : '1235467000' [1235467000] PC : 124 [124] Number : >< [00] Location : >000f 0034< [000f 0034] extension : >< Capability : >.< Info : >< Name : >Nick< [Nick} IC : '1235467000' [1235467000] PC : 124 [124] Number : >< [00] Location : >000f 0034< [000f 0034] extension : >< Capability : >.< Info : ><