我怎么知道我的列表中是否有号码?
How do I know if there is a number in my list?
我的代码如下所示:
#!/usr/bin/perl
$counter=0;
@list=<STDIN>;
chomp(@list);
if (@list==~ /^[+-]?\d+$/ )
{
$counter++;
}
print $counter;
所以我这样写数据:a b c d 1 2
然后它应该打印 2
因为 1,2
但是无论我在列表中写入什么数据我都会返回0
。
那么我的if
有什么问题?
总是use strict; use warnings;
。如果您的目标是计算列表中数字元素的数量,您可以使用 grep
过滤列表元素,然后应用 scalar
获取其长度(或直接使用 $length
将筛选后的列表存储在 @matches
):
#!/usr/bin/perl
use strict;
use warnings;
my @list = <STDIN>;
chomp(@list);
my @matches = grep /^[+-]?\d+$/, @list;
print scalar @matches . "\n";
样本运行:
$ ./count.pl
-62
a
b
4
c
+91023
d
3
老实说,看起来您只是猜到了这个语法。这并不是编写程序的好方法:-)
你的主要问题在这一行:
if (@list==~ /^[+-]?\d+$/ )
这里有两个相当大的问题。首先,@list
。匹配运算符 (=~
) 一次只处理一个字符串。所以你需要在标量值上使用它。如果你给它一个数组(就像你在这里所做的那样),那么 Perl 将(默默地)将数组计算为一个标量——这意味着你将获得数组中元素的数量,而不是获取数组的内容- 这将是一个整数,因此您的正则表达式将始终匹配。
但是,你说,不匹配。是的,我意识到这一点。这取决于你的第二个错误——你的匹配运算符是错误的。运算符是 =~
而您使用的是 ==~
(请参阅额外的 =
)。您希望这样的错误会导致语法错误,但您不小心使用了一个语法上有效的版本,但它并没有按照您的意愿执行。 Perl 将您的代码解释为:
if (@list = =~ /^[+-]?\d+$/ )
注意我添加的空格。两个 =
字符之间的一个很重要。这是说 "perform the match operation and assign the results to @list
"。但是匹配运算符匹配的对象是什么?好吧,它没有被赋予一个明确的变量来匹配,在这种情况下它匹配默认变量 $_
。你没有在 $_
中输入任何内容,所以匹配失败。
在这一点上,我应该指出,如果您的代码中有 use warnings
,那么您将收到关于您做错了什么的各种有用警告。所有 Perl 程序员(包括最有经验的)都应该在他们的代码中始终包含 use strict
和 use warnings
。
这里还有一个混淆点。这是您阅读输入的方式。
@list = <STDIN>;
你没有说清楚,但我怀疑你是在一行中输入你的列表。在这种情况下,您不想将输入存储在数组中;您应该将其存储在标量中。
chomp($list = <STDIN>);
然后您可以使用 split()
.
将其转换为列表(存储在数组中)
@list = split /\s+/, $list;
然后您可以使用 grep
.
获取数组中的数字计数
my $count = grep { /^[-+]\d+$/ } @list;
当作为标量计算时,grep
returns 代码块为真的次数。
将它们放在一起(并添加 strict
和 warnings
)我们得到以下内容:
#!/usr/bin/perl
use strict;
use warnings;
chomp(my $list = <STDIN>);
my $count = grep { /^[-+]\d+$/ } split /\s+/, $list;
至少在我看来,这看起来比你的版本简单。
我的代码如下所示:
#!/usr/bin/perl
$counter=0;
@list=<STDIN>;
chomp(@list);
if (@list==~ /^[+-]?\d+$/ )
{
$counter++;
}
print $counter;
所以我这样写数据:a b c d 1 2
然后它应该打印 2
因为 1,2
但是无论我在列表中写入什么数据我都会返回0
。
那么我的if
有什么问题?
总是use strict; use warnings;
。如果您的目标是计算列表中数字元素的数量,您可以使用 grep
过滤列表元素,然后应用 scalar
获取其长度(或直接使用 $length
将筛选后的列表存储在 @matches
):
#!/usr/bin/perl
use strict;
use warnings;
my @list = <STDIN>;
chomp(@list);
my @matches = grep /^[+-]?\d+$/, @list;
print scalar @matches . "\n";
样本运行:
$ ./count.pl
-62
a
b
4
c
+91023
d
3
老实说,看起来您只是猜到了这个语法。这并不是编写程序的好方法:-)
你的主要问题在这一行:
if (@list==~ /^[+-]?\d+$/ )
这里有两个相当大的问题。首先,@list
。匹配运算符 (=~
) 一次只处理一个字符串。所以你需要在标量值上使用它。如果你给它一个数组(就像你在这里所做的那样),那么 Perl 将(默默地)将数组计算为一个标量——这意味着你将获得数组中元素的数量,而不是获取数组的内容- 这将是一个整数,因此您的正则表达式将始终匹配。
但是,你说,不匹配。是的,我意识到这一点。这取决于你的第二个错误——你的匹配运算符是错误的。运算符是 =~
而您使用的是 ==~
(请参阅额外的 =
)。您希望这样的错误会导致语法错误,但您不小心使用了一个语法上有效的版本,但它并没有按照您的意愿执行。 Perl 将您的代码解释为:
if (@list = =~ /^[+-]?\d+$/ )
注意我添加的空格。两个 =
字符之间的一个很重要。这是说 "perform the match operation and assign the results to @list
"。但是匹配运算符匹配的对象是什么?好吧,它没有被赋予一个明确的变量来匹配,在这种情况下它匹配默认变量 $_
。你没有在 $_
中输入任何内容,所以匹配失败。
在这一点上,我应该指出,如果您的代码中有 use warnings
,那么您将收到关于您做错了什么的各种有用警告。所有 Perl 程序员(包括最有经验的)都应该在他们的代码中始终包含 use strict
和 use warnings
。
这里还有一个混淆点。这是您阅读输入的方式。
@list = <STDIN>;
你没有说清楚,但我怀疑你是在一行中输入你的列表。在这种情况下,您不想将输入存储在数组中;您应该将其存储在标量中。
chomp($list = <STDIN>);
然后您可以使用 split()
.
@list = split /\s+/, $list;
然后您可以使用 grep
.
my $count = grep { /^[-+]\d+$/ } @list;
当作为标量计算时,grep
returns 代码块为真的次数。
将它们放在一起(并添加 strict
和 warnings
)我们得到以下内容:
#!/usr/bin/perl
use strict;
use warnings;
chomp(my $list = <STDIN>);
my $count = grep { /^[-+]\d+$/ } split /\s+/, $list;
至少在我看来,这看起来比你的版本简单。