sub parse_HERE_table($) { my @lines = split /[\r\n]+/, $_[0]; my $pattern = splice @lines, 1, 1; my $len = length $pattern; $pattern =~ y/-/A/; # to use \b, we need \w chars, and '-' is not \w. $pattern =~ s/\bA/(A/g; # too bad we can't do s/\/)/g :-( $pattern =~ s/A\b/A)/g; $pattern =~ y/A/./; ( my $header, @lines ) = map { [ map { s/\s+$//; $_ } /$pattern/ ] } # parse; trim trailing whitespace from each value. map { $_.(' 'x($len-length($_))) } # pad with spaces to ensure it's long enough to match. grep { /\S/ } # skip blank lines. @lines; [ map { my %r; @r{ @$header } = @$_; \%r } @lines ] } my $arrayref = parse_HERE_table <