You've already got some ideas for parsing the input. For the conversion step, you could reach for CPAN and Geo::Coordinates::DecimalDegrees.
use strict;
use warnings;
use Geo::Coordinates::DecimalDegrees;
my ( $degrees, $minutes, $seconds ) = ( 23, 34, 6 );
my $decimal_degrees = dms2decimal( $degrees, $minutes, $seconds );
printf "%d:%d:%d => %.5f\n", $degrees, $minutes, $seconds, $decimal_de
+grees;
( $degrees, $minutes, $seconds ) = decimal2dms( $decimal_degrees );
printf "%.5f => %d:%d:%d\n", $decimal_degrees, $degrees, $minutes, $se
+conds;
Output:
23:34:6 => 23.56833
23.56833 => 23:34:5
Note that if precision is important you might want to peek at the code and run some tests. For the example above, a round trip conversion from DDMMSS => decimal degrees => DDMMSS results in a one second difference.
Update: Whups. The printf pattern isn't quite right. Many thanks to BrowserUk++ for catching the error and for providing a much better pattern: %d:%02d:%02.f