#!/usr/bin/perl -w use strict; use Data::Dumper; my @nums = qw/ 0xff 09h 123.25 14E+12 0xfffa 0xffffh 123.25t 777o 123.23.45 1.2e+13 /; foreach ( @nums ) { my $result = convert_num( $_ ); if ( $result->{ valid } ) { print "$_ is a $result->{base} number with a $result->{value} decimal value.\n"; } else { print "$_ is not a valid number.\n"; } } sub convert_num { my $num = shift; my %bases = ( hex => { description => [ qw/ ^0x[A-Fa-f0-9]+$ ^[A-Fa-f0-9]+h$ / ], function => sub { ( $_[0] ) = ( $_[0] =~ /(?:0x)?([a-fA-F0-9]+)/ ); hex( $_[0] ) } }, octal => { description => [ '^[0-7]+o$' ], function => sub { ( $_[0] ) = ( $_[0] =~ /([0-7]+)/ ); oct( $_[0] ) } }, decimal => { description => [ qw/ ^\d*\.\d+(?!\.)\d*t?$ / ], function => sub { $_[0] =~ s/t$//; $_[0] } }, scientific => { description => [ '^\d*\.?\d+(?!\.)\d*[Ee]\+\d+$' ], function => sub { 1 * shift } } ); my %result = ( valid => 0, base => '', value => $num ) ; foreach my $base ( keys %bases ) { foreach my $regex ( @{ $bases{$base}{description} } ) { if ( $num =~ /$regex/ ) { $result{ valid }++; $result{ base } = $base; } } } if ( $result{ valid } != 1 ) { @result{ qw/ valid base value / } = ('','',''); } else { my $function = $bases{ $result{ base } }{ function }; $result{ value } = $function->( $num ); } return \%result; }