Both of these fail. .*? is the non-greedy version, not .*+, so s/\..*+$// fails on compile, and still doesn't work right if debugged because it's matching off of the first period. Your second expression has a typo (- in place of .) so it should read s/\.[^\.]*$//, as per dreadpiratepeter's post.