指定された変数が数値かどうかを判断できる簡単な方法は Perl にありますか? 次のようなもの:
if (is_number($x))
{ ... }
理想的でしょう。-w
スイッチが使用されているときに警告をスローしない手法は、確かに好まれます。
内部 Perl C API の look_like_number() 関数を使用するScalar::Util::looks_like_number()
ものを使用します。これはおそらくこれを行う最も効率的な方法です。文字列 "inf" と "infinity" は数値として扱われることに注意してください。
#!/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";
}
次の出力が得られます。
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
looks_like_number
元々の質問は、変数が「数値を持っている」かどうかではなく、変数が数値であるかどうかをどのように判断するかでした。
数値オペランドと文字列オペランドに別々の操作モードを持つ演算子がいくつかあります。「数値」とは、元々数値であったか、数値コンテキストで使用されたことがあるものを意味します(たとえば$x = "123"; 0+$x
、加算前は$x
文字列であり、その後は文字列です)。数値と見なされます)。
伝える1つの方法はこれです:
if ( length( do { no warnings "numeric"; $x & "" } ) ) {
print "$x is numeric\n";
}
ビット演算子が有効になっている場合、つまり&
数値演算子のみが作成され、別の文字列演算子が追加される&.
場合は、無効にする必要があります。
if ( length( do { no if $] >= 5.022, "feature", "bitwise"; no warnings "numeric"; $x & "" } ) ) {
print "$x is numeric\n";
}
(bitwiseはperl 5.022以降で使用可能であり、それ以上の場合はデフォルトで有効になっていますuse 5.028;
。)
CPAN モジュールRegexp::Commonを調べてください。必要なことを正確に実行し、すべてのエッジケース(実数、科学表記法など)を処理すると思います。例えば
use Regexp::Common;
if ($var =~ /$RE{num}{real}/) { print q{a number}; }
通常、数値の検証は正規表現で行われます。このコードは、何かが数値であるかどうかを判断し、未定義の変数をチェックして警告をスローしないようにします。
sub is_integer {
defined $_[0] && $_[0] =~ /^[+-]?\d+$/;
}
sub is_float {
defined $_[0] && $_[0] =~ /^[+-]?\d+(\.\d+)?$/;
}
ここにあなたが見るべきいくつかの読み物があります。
質問に対する単純な(そしておそらく単純な)答えは、数値の内容は$x
次のとおりです。
if ($x eq $x+0) { .... }
元の値と数値$x
に変換された値をテキストで比較します。$x
それを行うための組み込み機能はないと思います。この件に関してあなたが見たいと思っていた以上のものについては、 Perlmonks on Detecting Numericを参照してください。
完全ではありませんが、正規表現を使用できます。
sub isnumber
{
shift =~ /^-?\d+\.?\d*$/;
}
rexepは完璧ではありません...これは:
use Try::Tiny;
sub is_numeric {
my ($x) = @_;
my $numeric = 1;
try {
use warnings FATAL => qw/numeric/;
0 + $x;
}
catch {
$numeric = 0;
};
return $numeric;
}
Regexp::Commonには、もう少し堅牢な正規表現があります。
Perl が変数を数値と見なしているかどうかを知りたいようです。その警告をトラップする関数は次のとおりです。
sub is_number{
my $n = shift;
my $ret = 1;
$SIG{"__WARN__"} = sub {$ret = 0};
eval { my $x = $n + 1 };
return $ret
}
別のオプションは、警告をローカルでオフにすることです。
{
no warnings "numeric"; # Ignore "isn't numeric" warning
... # Use a variable that might not be numeric
}
数値以外の変数は暗黙のうちに 0 に変換されることに注意してください。
これは面白いと思ったけど
if ( $value + 0 eq $value) {
# A number
push @args, $value;
} else {
# A string
push @args, "'$value'";
}
これを試して:
If (($x !~ /\D/) && ($x ne "")) { ... }
正規表現を使用して、$foo が数値であるかどうか (または数値でないか) を判別できます。
ここを見てください: スカラーが数値かどうかを判断するにはどうすればよいですか
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.