use strict; my $regex = qr/(\d\d):(\d\d)(?::(\d\d))?/; # 01234567890123456 my $string = "11:30 or 11:29:53"; my $res; while ($string =~ /$regex/g) { my $pos = $-[0]; my ($ind, @match); for $ind (1..$#-) { push @match, substr ($string, $-[$ind], $+[$ind] - $-[$ind]); } $res->{$pos} = \@match; } use Data::Dumper; print Data::Dumper::Dumper $res; #### $VAR1 = { '0' => [ '11', '30' ], '9' => [ '11', '29', '53' ] };