Frage Wie kann ich feststellen, ob eine Variable in Perl einen numerischen Wert hat?


Gibt es einen einfachen Weg in Perl, mit dem ich feststellen kann, ob eine gegebene Variable numerisch ist? Etwas in der Art von:

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

wäre ideal. Eine Technik, die keine Warnungen auslöst, wenn der -w Schalter wird verwendet wird sicherlich bevorzugt.


75
2017-08-15 19:43


Ursprung


Antworten:


Benutzen Scalar::Util::looks_like_number() Das verwendet die interne Funktion der Lookup_like_number () - Funktion der internen Perl C-API. Dies ist wahrscheinlich der effizienteste Weg, dies zu tun. Beachten Sie, dass die Strings "inf" und "infinity" als Zahlen behandelt werden.

Beispiel:

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

Gibt diese Ausgabe:

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

siehe auch:

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

114
2017-08-26 16:53



Überprüfen Sie das CPAN-Modul Regexp :: Allgemein. Ich denke, es tut genau das, was Sie brauchen, und behandelt alle Randfälle (z. B. reelle Zahlen, wissenschaftliche Notation usw.). z.B.

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

23
2017-08-15 21:01



Die ursprüngliche Frage war, wie man feststellen kann, ob eine Variable numerisch ist, nicht, wenn sie "einen numerischen Wert hat".

Es gibt einige Operatoren, die separate Betriebsmodi für numerische Operatoren und Zeichenfolgenoperanden haben, wobei "numerisch" alles bedeutet, das ursprünglich eine Zahl war oder jemals in einem numerischen Kontext verwendet wurde (z. B. in $x = "123"; 0+$xvor der Zugabe $x ist eine Zeichenkette, danach wird sie als numerisch betrachtet).

Eine Möglichkeit zu sagen ist das:

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

20
2017-09-27 17:16



Eine einfache (und vielleicht simple) Antwort auf die Frage ist der Inhalt von $x numerisch ist das Folgende:

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

Es macht einen textuellen Vergleich des Originals $x mit dem $x in einen numerischen Wert konvertiert.


8
2017-10-17 15:10



Normalerweise erfolgt die Überprüfung der Zahlen mit regulären Ausdrücken. Dieser Code wird bestimmen, ob etwas numerisch ist, und nach nicht definierten Variablen suchen, um keine Warnungen auszugeben:

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

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

Hier sind einige Lesestoff Sie sollten sich anschauen.


7
2017-08-15 19:58



Nicht perfekt, aber Sie können eine Regex verwenden:

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

3
2017-08-15 19:49



Ich glaube nicht, dass da etwas eingebaut ist. Für mehr, als Sie jemals zu dem Thema sehen wollten, siehe Perlmonks beim Erkennen von Zahlen


3
2017-08-15 20:44



Ein etwas robusterer Regex findet sich in Regexp :: Allgemein.

Es klingt, als ob Sie wissen möchten, ob Perl eine Variable für numerisch hält. Hier ist eine Funktion, die diese Warnung auffängt:

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

Eine andere Möglichkeit ist, die Warnung lokal zu deaktivieren:

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

Beachten Sie, dass nicht numerische Variablen automatisch in 0 konvertiert werden. Dies ist wahrscheinlich das, was Sie trotzdem wollten.


2
2017-08-15 20:56



rexep nicht perfekt ... das ist:

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



Versuche dies:

If (($x !~ /\D/) && ($x ne "")) { ... }

1
2018-05-31 16:01



Ich fand das aber interessant

if ( $value + 0 eq $value) {
    # A number
    push @args, $value;
} else {
    # A string
    push @args, "'$value'";
}

1
2017-10-01 14:15