Pregunta ¿Cómo puedo saber si una variable tiene un valor numérico en Perl?


¿Hay alguna manera simple en Perl que me permita determinar si una variable dada es numérica? Algo como:

if (is_number($x))
{ ... }

sería ideal Una técnica que no lanzará advertencias cuando -w El interruptor que se usa es ciertamente preferido.


75
2017-08-15 19:43


origen


Respuestas:


Utilizar Scalar::Util::looks_like_number() que usa la función interna de Perl C API looks_like_number (), que es probablemente la forma más eficiente de hacerlo. Tenga en cuenta que las cadenas "inf" e "infinito" se tratan como números.

Ejemplo:

#!/usr/bin/perl

use warnings;
use strict;

use Scalar::Util qw(looks_like_number);

my @exprs = qw(1 5.25 0.001 1.3e8 foo bar 1dd inf infinity);

foreach my $expr (@exprs) {
    print "$expr is", looks_like_number($expr) ? '' : ' not', " a number\n";
}

Da esta salida:

1 is a number
5.25 is a number
0.001 is a number
1.3e8 is a number
foo is not a number
bar is not a number
1dd is not a number
inf is a number
infinity is a number

ver también:

[perldoc Scalar::Util][1]
[perldoc perlapi][2] 

114
2017-08-26 16:53



Vea el módulo de CPAN Regexp :: Común. Creo que hace exactamente lo que necesita y maneja todos los casos extremos (por ejemplo, números reales, notación científica, etc.). p.ej.

use Regexp::Common;
if ($var =~ /$RE{num}{real}/) { print q{a number}; }

23
2017-08-15 21:01



La pregunta original era cómo decir si una variable era numérica, no si "tiene un valor numérico".

Hay algunos operadores que tienen modos de operación separados para operandos numéricos y de cadena, donde "numérico" significa cualquier cosa que originalmente era un número o que alguna vez se usó en un contexto numérico (por ejemplo, $x = "123"; 0+$xantes de la adición $x es una cadena, luego se considera numérica).

Una forma de decir es esto:

if ( length( do { no warnings "numeric"; $x & "" } ) ) {
    print "$x is numeric\n";
}

20
2017-09-27 17:16



Una respuesta simple (y tal vez simplista) a la pregunta es el contenido de $x numérico es el siguiente:

if ($x  eq  $x+0) { .... }

Hace una comparación textual del original $x con el $x convertido a un valor numérico


8
2017-10-17 15:10



Por lo general, la validación del número se realiza con expresiones regulares. Este código determinará si algo es numérico y también buscará variables indefinidas para no lanzar advertencias:

sub is_integer {
   defined $_[0] && $_[0] =~ /^[+-]?\d+$/;
}

sub is_float {
   defined $_[0] && $_[0] =~ /^[+-]?\d+(\.\d+)?$/;
}

Aquí hay algunos material de lectura deberías mirar.


7
2017-08-15 19:58



No es perfecto, pero puedes usar una expresión regular:

sub isnumber 
{
    shift =~ /^-?\d+\.?\d*$/;
}

3
2017-08-15 19:49



No creo que haya nada integrado para hacerlo. Por más de lo que siempre quiso ver sobre el tema, vea Perlmonks en Detectar Numérico


3
2017-08-15 20:44



Se puede encontrar una expresión regular un poco más robusta en Regexp :: Común.

Parece que quieres saber si Perl cree que una variable es numérica. Aquí hay una función que atrapa esa advertencia:

sub is_number{
  my $n = shift;
  my $ret = 1;
  $SIG{"__WARN__"} = sub {$ret = 0};
  eval { my $x = $n + 1 };
  return $ret
}

Otra opción es desactivar la advertencia localmente:

{
  no warnings "numeric"; # Ignore "isn't numeric" warning
  ...                    # Use a variable that might not be numeric
}

Tenga en cuenta que las variables no numéricas se convertirán en silencio a 0, que es probablemente lo que quería de todos modos.


2
2017-08-15 20:56



rexep no es perfecto ... esto es:

use Try::Tiny;

sub is_numeric {
  my ($x) = @_;
  my $numeric = 1;
  try {
    use warnings FATAL => qw/numeric/;
    0 + $x;
  }
  catch {
    $numeric = 0;
  };
  return $numeric;
}

2
2017-12-10 18:58