How do I tell if a variable has a numeric value in Perl?

前端 未结 14 1345
别那么骄傲
别那么骄傲 2020-11-28 06:56

Is there a simple way in Perl that will allow me to determine if a given variable is numeric? Something along the lines of:

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


        
相关标签:
14条回答
  • 2020-11-28 07:21

    I don't believe there is anything builtin to do it. For more than you ever wanted to see on the subject, see Perlmonks on Detecting Numeric

    0 讨论(0)
  • 2020-11-28 07:25

    if ( defined $x && $x !~ m/\D/ ) {} or $x = 0 if ! $x; if ( $x !~ m/\D/) {}

    This is a slight variation on Veekay's answer but let me explain my reasoning for the change.

    Performing a regex on an undefined value will cause error spew and will cause the code to exit in many if not most environments. Testing if the value is defined or setting a default case like i did in the alternative example before running the expression will, at a minimum, save your error log.

    0 讨论(0)
  • 2020-11-28 07:28

    Check out the CPAN module Regexp::Common. I think it does exactly what you need and handles all the edge cases (e.g. real numbers, scientific notation, etc). e.g.

    use Regexp::Common;
    if ($var =~ /$RE{num}{real}/) { print q{a number}; }
    
    0 讨论(0)
  • 2020-11-28 07:31

    Use Scalar::Util::looks_like_number() which uses the internal Perl C API's looks_like_number() function, which is probably the most efficient way to do this. Note that the strings "inf" and "infinity" are treated as numbers.

    Example:

    #!/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";
    }
    

    Gives this output:

    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
    

    See also:

    • perldoc Scalar::Util
    • perldoc perlapi for looks_like_number
    0 讨论(0)
  • 2020-11-28 07:32

    Personally I think that the way to go is to rely on Perl's internal context to make the solution bullet-proof. A good regexp could match all the valid numeric values and none of the non-numeric ones (or vice versa), but as there is a way of employing the same logic the interpreter is using it should be safer to rely on that directly.

    As I tend to run my scripts with -w, I had to combine the idea of comparing the result of "value plus zero" to the original value with the no warnings based approach of @ysth:

    do { 
        no warnings "numeric";
        if ($x + 0 ne $x) { return "not numeric"; } else { return "numeric"; }
    }
    
    0 讨论(0)
  • 2020-11-28 07:33

    Not perfect, but you can use a regex:

    sub isnumber 
    {
        shift =~ /^-?\d+\.?\d*$/;
    }
    
    0 讨论(0)
提交回复
热议问题