仅为数字计算Perl字符串为零

时间:2012-07-09 15:00:00

标签: perl

我有一种情况,我希望变量以字符串或数字的形式传递给我。

sub foo {
    # These can be either strings or numbers
    my ($bar, $var, $star) = @_;

    # I need to check to see if $bar is the number 0 (zero)
    if ($bar == 0) {
        # Do super magic with it
    }
}

不幸的是,当Perl包含一个字符串时,它试图在$bar上执行超级魔法。

当且仅当数字 0(零)时,我如何告诉Perl在$bar上做超级魔法?

我理解Perl从根本上解释了上下文,这是这里的根本问题。这个问题的一个可能的解决方案是使用正则表达式,这很好,但我想知道是否还有另一个更“直接”的解决方案。

提前致谢。

4 个答案:

答案 0 :(得分:4)

我个人会接受@Disco3的评论所说的话。

if ($bar eq 0) { ... }

适用于$bar = 0$bar = 'foo'$bar = 123,可获得预期效果。

但这是一个有趣的事实:

use Benchmark qw(cmpthese);
my $bar = '0';

cmpthese(-1, {
  'quoted'    => sub { $bar eq '0'    },
  'unquoted'  => sub { $bar eq 0      },
  'regex'     => sub { $bar =~ m/^0$/ },
});

对这三个解决方案进行基准测试告诉我们,不带引号的0是最快的方法。

               Rate    regex   quoted unquoted
regex     4504851/s       --     -70%     -76%
quoted   15199885/s     237%       --     -19%
unquoted 18828298/s     318%      24%       --

答案 1 :(得分:2)

为什么不:

if ( $bar =~ m/^0$/ ) {

答案 2 :(得分:2)

这取决于你的意思是“数字0”。显然,您包含一个字符串0为零。但你对三个字符串0.0的看法是什么?

如果您只想匹配一个字符串0,请使用

if ($bar eq '0') {
   ...
}

如果要匹配Perl认为的数字为零,请使用

use Scalar::Util qw( looks_like_number );

if (looks_like_number($bar) && $bar == 0) {
   ...
}

答案 3 :(得分:0)

looks_like_number和数字比较之间,你可以很容易地得到相当好的结果:

use Scalar::Util qw(looks_like_number);
use Test::More tests => 7;

sub is_numerically_zero {
    my ($string) = @_;

    return (looks_like_number($string) and $string == 0);
}

for my $string (qw(0 0.0 0e0), '  0  ') {
    ok(is_numerically_zero($string));
}

for my $string (qw(duckies 123), '') {
    ok(not is_numerically_zero($string));
}

这假设您不希望仅匹配文字字符串'0'