【发布时间】:2017-10-13 03:30:57
【问题描述】:
每次我输入一些东西时,代码总是告诉我它存在。但我知道有些输入不存在。怎么了?
#!/usr/bin/perl
@array = <>;
print "Enter the word you what to match\n";
chomp($match = <STDIN>);
if (grep($match, @array)) {
print "found it\n";
}
【问题讨论】:
每次我输入一些东西时,代码总是告诉我它存在。但我知道有些输入不存在。怎么了?
#!/usr/bin/perl
@array = <>;
print "Enter the word you what to match\n";
chomp($match = <STDIN>);
if (grep($match, @array)) {
print "found it\n";
}
【问题讨论】:
您给 grep 的第一个参数需要评估为 true 或 false 以指示是否存在匹配项。所以应该是:
# note that grep returns a list, so $matched needs to be in brackets to get the
# actual value, otherwise $matched will just contain the number of matches
if (my ($matched) = grep $_ eq $match, @array) {
print "found it: $matched\n";
}
如果您需要匹配许多不同的值,您可能还值得考虑将 array 数据放入 hash,因为哈希允许您高效地执行此操作而无需遍历列表。
# convert array to a hash with the array elements as the hash keys and the values are simply 1
my %hash = map {$_ => 1} @array;
# check if the hash contains $match
if (defined $hash{$match}) {
print "found it\n";
}
【讨论】:
您似乎在使用 grep() 就像 Unix 的 grep 实用程序,这是错误的。
Perl 在标量上下文中的grep() 计算列表中每个元素的表达式并返回表达式为真的次数。
因此,当$match 包含任何“真”值时,标量上下文中的grep($match, @array) 将始终返回@array 中的元素数。
请尝试使用模式匹配运算符:
if (grep /$match/, @array) {
print "found it\n";
}
【讨论】:
这可以使用List::Util 的first 函数来完成:
use List::Util qw/first/;
my @array = qw/foo bar baz/;
print first { $_ eq 'bar' } @array;
List::Util 的其他功能,如 max、min、sum 也可能对您有用
【讨论】:
除了 eugene 和 stevenl 发布的内容之外,您可能会遇到在一个脚本中同时使用 <> 和 <STDIN> 的问题:<> 遍历(=连接)作为命令行参数给出的所有文件。
但是,如果用户忘记在命令行上指定文件,它将从 STDIN 读取,并且您的代码将永远等待输入
【讨论】:
如果您的数组包含字符串“hello”,并且如果您正在搜索“he”,那么 grep 可能会返回 true,尽管“he”可能不是数组元素。
也许,
if (grep(/^$match$/, @array)) 更贴切。
【讨论】:
您还可以检查多个数组中的单个值,例如,
if (grep /$match/, @array, @array_one, @array_two, @array_Three)
{
print "found it\n";
}
【讨论】: