use strict; use warnings; use Data::Dumper; my %blocks; local $/ = ''; while () { my ($type) = /block_type=(A|B)/; my ($id) = /block_id=(\d+)/; unless ($type && $id) { warn "Invalid block syntax in record $.\n$_\n"; next; } $blocks{$type}[$id] = $_; } print Dumper \%blocks; __DATA__ # A type A block block_type=A block_id=1 magic=true unlikeliness=2 # Another type A block block_type=A block_id=2 magic=false unlikeliness=9 # A type B block block_type=B block_id=1 colour=green warty=false horns=1 # Another type B block block_type=B block_id=2 colour=red warty=false horns=7 # A further type B block block_type=B block_id=3 colour=red warty=true horns=1