$str = 'first name EOFlast name EOFaddress field EOF'; my @rec_def = ( [ 'first_name', 20 ], [ 'last_name', 20 ], [ 'address', 30 ], ); sub parse_fixed_width { my ( $record, $rec_def ) = @_; my %struct; my $offset = 0; for my $rec(@$rec_def) { $struct{$rec->[0]} = substr $record, $offset, $rec->[1]; $offset += $rec->[1]; } return length($record) == $offset ? \%struct : ''; } use Data::Dumper; print Dumper parse_fixed_width( $str, \@rec_def ); __DATA__ $VAR1 = { 'first_name' => 'first name EOF', 'address' => 'address field EOF', 'last_name' => 'last name EOF' };