通过比较现有数组验证用户输入的perl程序

通过比较现有数组验证用户输入的perl程序,perl,Perl,我正在尝试编写一个Perl脚本来验证用户输入。 如果用户提供了错误的值,则应显示所提供的用户输入中的错误值 例如: 我有任何数组@arr=qw/cat-rat-mat-sat/ 如果用户以perl validate_user_input.pl cat sot bat的形式提供输入,那么我的脚本应该显示sot bat是错误的脚本输入 下面是我正在尝试的脚本 #!/usr/bin/perl use strict; use warnings; my (@not,@arr,$flag); @arr=

我正在尝试编写一个Perl脚本来验证用户输入。 如果用户提供了错误的值,则应显示所提供的用户输入中的错误值

例如:

我有任何数组@arr=qw/cat-rat-mat-sat/

如果用户以perl validate_user_input.pl cat sot bat的形式提供输入,那么我的脚本应该显示sot bat是错误的脚本输入

下面是我正在尝试的脚本

#!/usr/bin/perl

use strict;
use warnings;

my (@not,@arr,$flag);
@arr=qw/cat rat mat sat/;
my $count=@arr;
foreach (@ARGV)
{
         my $i=1;
        foreach my $existing (@arr)
        {

                until ( "$existing" eq "$_" )
                {

                        $flag = 1;
                        $i++;
                        last;
                }

        }

        print "$i\n";
        if ( ($count==$i) && ($flag == 1))
        {
                push(@not,"$_");
        }
}
print "@not\n";
我试图实现的逻辑:

@ARGV中的元素将根据@arr的每个元素进行检查。如果$flag=1且迭代$i等于@arr中的元素数,即根据@arr中的所有元素进行检查,则在@arr中找不到输入


谁能告诉我这个脚本需要做什么才能正常工作。

太复杂了。将“有效”参数转换为哈希,然后使用grep:

如果愿意,如果想继续,可以在该foreach循环中设置一个标志。或者在标量上下文中使用grep:

if ((grep { not $is_allowed{$_} } @ARGV) > 0 ) { 
   die "invalid args found, exiting\n"
}

对这个网站的简短搜索会让我相信你把事情复杂化了:

#!/usr/bin/env perl

use strict;
use warnings;

my (@not,@arr);
@arr=qw/cat rat mat sat/;

foreach (@ARGV)
{

        push(@not,"$_") unless ( "$_" ~~ @arr );
}
print "@not\n";
smart match操作符~~在我的5.24版本bash上仍然是“实验性的”,但它似乎至少从5.10开始就存在了


您可能还想在末尾添加某种测试,以检查@not是否包含任何内容,因为可能已经找到了所有单词。您可以重新使用您的标志:

将有效参数放入哈希%valid中,而不是数组@arr。然后您可以执行以下操作:

for (@ARGV) {
    push @not, $_ if !exists $valid{$_};
}
使用

输出

OK cat : 2
OK rat : 1
OK mat : 1
OK sat : 0
NO bar : 1
NO bat : 1
NO ded : 1
NO foo : 2

直到=>如果是初学者。也许任何人都会比grep更干净…>0 ? 你在第一个版本中留下了一个@假装ARGV,我不确定这是测试的遗留问题还是故意的。可能是,是的。是的,我使用@假装ARGV进行测试:我会在地图上加一个1,这样你就可以检查“真实”和“存在”。@Sobrique Yikes!但正如你所看到的,对于像我这样的初学者来说,这更具表现力。Ofc,你说得对
use strict;
use warnings;

my @arr=qw(cat rat mat sat);
my $ok = { map{ $_ => 0 } @arr};
my $wrong;
exists $ok->{$_} ? $ok->{$_}++ : $wrong->{$_}++ for @ARGV;

print "OK $_ : $ok->{$_}\n" for @arr;
print "NO $_ : $wrong->{$_}\n" for (sort keys %$wrong);
perl arg.pl bat cat ded rat mat foo bar foo cat
OK cat : 2
OK rat : 1
OK mat : 1
OK sat : 0
NO bar : 1
NO bat : 1
NO ded : 1
NO foo : 2