use warnings; use strict; MAIN: { my $month_rx = month_names_regex(); while () { s{ ($month_rx) }{ "$1 (@{[ month_number($1) ]})" }xmseg; print; } } BEGIN { # compile-time initialized closure for month-number regexes my %months; # start with long names of months, pair with month number strings. # month numbers: two digits with leading zero if needed. # all month names in common lower case. @months{ qw( january february march april may june july august september october november december ) } = map { sprintf '%02d', $_ } 1 .. 12; # generate short month names, pair with long month numbers. my $months_re = join ' | ', map { my ($short_name, $regex) = mon_split($_); $months{$short_name} = $months{$_}; $regex; } keys %months ; # return final long/short month name regex. sub month_names_regex { return qr{ \b (?: $months_re) \b }xmsi } # convert long/short month name to month number. sub month_number { my $name = shift; return $months{lc $name} } # printf "\$months_re is %s \n", month_names_regex(); # FOR DEBUG # print "$_ => $months{$_} \n" for keys %months; # FOR DEBUG sub mon_split { my ($mon_name, ) = @_; my ($head, $tail) = $mon_name =~ m{ \A (\w{3}) (\w*) \z }xms; die "malformed month name $mon_name" unless $head; $tail = qr{ (?: $tail)? }xmsi if $tail; return (lc $head, qr{ $head $tail }xmsi); } } # end compile-time initialized closure for month-number regexes __DATA__ jan january february feb mar march jUnE JuN JuLy JUL xMaY xmArx Marx xmay xmayx mayx xjunE xjunex xJUNEx xjun xJUNx jUnx and so on