If you're certain that the file names are always as simple as you described (one dot per name), then you can use fileparse without an extension arg; this leaves the extension attached in the return value, which you can then split on period:
use File::Basename;
for ( qw{foo/bar.ext ../moo/mar.ble} ) {
my ( $name, $ext ) = split( /\./, fileparse( $_ ));
print "$_ => $name and $ext\n";
}