use 5.010; my $source = 'function convert(beg string, end string, read_date date, step char(6)) returns (date, date, char(1))'; my $matched = $source =~ m{ \A \s*+ (? private | public )?+ \s*+ (? function | report ) \s*+ (? (?&identifier) ) \s*+ (? (?&list) ) \s*+ (returns \s*+ (? (?&list) ) )?+ \s*+ \z (?(DEFINE) (? [^\W\d]\w*+ ) (? [(] [^()]*+ (?: (?&list) [^()]*+ )*+ [)] ) ) }xms; if ($matched) { my %components = %+; use Data::Dumper 'Dumper'; say Dumper \%components; } else { say 'parse failed'; }