# set imput record separator to end of table string $/ = "\n\n"; my %hash; # now we are reading data a table at a time while() { my ( undef, $header, $data ) = split /\+\-+\+\s*/, $_; $header =~ s/\s*\|\s*//g; @data = $data =~ m/\|([^\|]+)\|/g; push @{$hash{$header}}, @data; } use Data::Dumper; print Dumper \%hash; __DATA__ +---------+ | formula | +---------+ | dat1 | | dat2 | | dat3 | +---------+ +---------+ | formula | +---------+ | dat4 | | dat5 | | dat6 | +---------+ +---------+ | flubber | +---------+ | dat11 | | dat22 | | dat33 | +---------+ +---------+ | dubber | +---------+ | dat111 | | dat222 | | dat333 | +---------+ +---------+ | dubber | +---------+ | dat1111 | | dat2222 | | dat3333 | +---------+ __END__ $VAR1 = { '' => [], 'flubber' => [ ' dat11 ', ' dat22 ', ' dat33 ' ], 'formula' => [ ' dat1 ', ' dat2 ', ' dat3 ', ' dat4 ', ' dat5 ', ' dat6 ' ], 'dubber' => [ ' dat111 ', ' dat222 ', ' dat333 ', ' dat1111 ', ' dat2222 ', ' dat3333 ' ] };