Assumendo che non vi importi delle notazioni IEEE come "NaN" o "Infinity",
probabilmente vi basta usare una espressione regolare.
if (/\D/) { print "contiene caratteri non cifra\n" }
if (/^\d+$/) { print "e` un numero naturale\n" }
if (/^-?\d+$/) { print "e` un intero\n" }
if (/^[+-]?\d+$/) { print "e` un intero con +/-\n" }
if (/^-?\d+\.?\d*$/) { print "e` un numero reale\n" }
if (/^-?(?:\d+(?:\.\d*)?|\.\d+)$/) { print "e` un numero decimale\n" }
if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/)
{ print "un numero in virgola mobile del C\n" }
Ci sono anche alcuni moduli d'uso comune per questo compito.
Scalar::Util (distribuito con 5.8) fornisce l'accesso alla funzione
interna di perl looks_like_number per determinare se una variabile
assomiglia ad un numero. Data::Types esporta funzioni che validano
i tipi di dato utilizzando sia le precedenti espressioni regolari sia altre.
Terzo, c'è Regexp::Common che ha espressioni regolari per
riconoscere diversi tipi di numeri. Questi tre moduli sono
disponibili da CPAN.
Se vi trovate su un sistema POSIX, Perl supporta la funzione
POSIX::strtod. La sue semantica è un po' scomoda, per cui
eccovi prendi_num, una funzione di comodo. Questa funzione prede una
stringa e restituisce il numero che ha trovato, oppure undef per un
input che non è un numero in virgola mobile del C. La funzione
controlla_num è un'interfaccia a prendi_num se si vuole solo
chiedere "Questo è un numero in virgola mobile?"
sub prendi_num {
use POSIX qw(strtod);
my $str = shift;
$str =~ s/^\s+//;
$str =~ s/\s+$//;
$! = 0;
my($num, $non_riconosciuto) = strtod($str);
if (($str eq '') || ($non_riconosciuto != 0) || $!) {
return undef;
} else {
return $num;
}
}
sub controlla_num { defined prendi_num($_[0]) }
Potreste invece dare un'occhiata al modulo String::Scanf
su CPAN. Il modulo POSIX (parte della distribuzione Perl standard) fornisce
strtod e strtol per convertire stringhe in, rispettivamente, numero in
virgola mobile e interi.
|