遍历数组的元素以查找字符 perl



我有一个perl数组,我只想循环访问元素2-8。

这些元素只意味着包含数字,所以如果这些元素中的任何一个包含字母,我想设置一个error flag = 1,以及一些其他变量。

我有 2 个错误标志变量的原因是循环中的范围规则。

fields是一个数组,我是通过" "键拆分另一个不相关的数组来创建的。

因此,当我尝试从循环外部打印error_line2, error_fname2时,我得到以下结果:

Use of uninitialized value $error_flag2 in numeric eq (==) 

我不知道为什么,因为我已经在循环中初始化了值并在循环外创建了变量。不确定我什至是否循环以正确查找字符,因此它没有设置error_flag2 = 1.

示例行:

bob hankerman 2039 3232 23 232 645 64x3 324

由于元素 7 有字母"x",我希望将标志设置为 1。

#!/usr/bin/perl
use strict;
use warnings;
use Scalar::Util qw(looks_like_number);
my $players_file = $ARGV[0];
my @players_array;
open (my $file, "<", "$players_file")
    or die "Failed to open file: $!n";
while(<$file>) {
    chomp;
    push @players_array, $_;
}
close $file;
#print join "n", @players_array;
my $num_of_players = @players_array;
my $error_flag;
my $error_line;
my $error_fname;
my $error_lname;
my $error_flag2=1;
my $error_line2;
my $error_fname2;
my $error_lname2;
my $i;
foreach my $player(@players_array){
    my @fields = split " ", $player;
    my $size2 = @fields;    
        for($i=2; $i<9; $i++){
    print "$fields[$i] n";
            if (grep $_ =~ /^[a-zA-Z]+$/){
                my $errorflag2 = 1;
                $error_flag2 = $errorflag2;
                my $errorline2 = $player +1;
                $error_line2 = $errorline2;
                my $errorfname2 = $fields[0];
                $error_fname2 = $errorfname2;               
            }
        }
    if ($size2 ==  "9" ) {
        my $firstname = $fields[0];
        my $lastname = $fields[1];
        my $batting_average = ($fields[4]+$fields[5]+$fields[6]+$fields[7]) / $fields[3];
        my $slugging = ($fields[4]+($fields[5]*2)+($fields[6]*3)+($fields[7]*4)) / $fields[3];
        my $on_base_percent = ($fields[4]+$fields[5]+$fields[6]+$fields[7] +$fields[8]) / $fields[2];
        print "$firstname ";
        print "$lastname ";
        print "$batting_average ";
        print "$slugging ";
        print "$on_base_percentn ";
    }
    else {
        my $errorflag = 1;
        $error_flag = $errorflag;
        my $errorline = $player +1;
        $error_line = $errorline;
        my $errorfname = $fields[0];
        $error_fname = $errorfname;
        my $errorlname = $fields[1];
        $error_lname = $errorlname;
    }
}
if ($error_flag == "1"){
        print "n Line $error_line : ";
    print "$error_fname, ";
        print "$error_lname :";
    print "Line contains not enough data.n";
}
if ($error_flag2 == "1"){
        print "n Line $error_line2 : ";
        print "$error_fname2, ";
        print "Line contains bad data.n";
}

好的,所以你在这里遇到的问题是你正在考虑用Unix术语grep - 一个基于文本的东西。它在 perl 中不是这样工作的 - 它在列表上运行。

幸运的是,这在您的情况下很容易处理,因为您可以将您的行split成文字。

如果没有您的源数据,这有望成为概念证明:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

while ( <DATA> ) { 
   #split the current line on whitespace into an array. 
   #first two elements  get assigned to firstname lastname, and then the rest  
   #goes into @values
   my ( $firstname, $lastname, @values ) = split; #works on $_ implicitly.
   #check every element in @values, and test the regex 'non-digit' against it. 
   my @errors = grep { /D/ } @values;
   #output any matches e.g. things that contained 'non-digits' anywhere. 
   print Dumper @errors; 
   #an array in a scalar context evaluates as the number of elements. 
   #we need to use "scalar" here because print accepts list arguments. 
   print "There were ", scalar @errors, " errorsn";
}
__DATA__
bob hankerman 2039 3232 23 232 645 64x3 324

或者简化逻辑:

#!/usr/bin/perl
use strict;
use warnings;
while ( <DATA> ) { 
   #note - we don't need to explicity specify 'scalar' here,
   #because assigning it to a scalar does that automatically. 
   #(split) splits the current line, and [2..8] skips the first two. 
   my $count_of_errors = grep { /D/ } (split)[2..8];       
   print $count_of_errors;
}
__DATA__
bob hankerman 2039 3232 23 232 645 64x3 324

首先:你不需要使用"GREP",只需在perl中将字符串与"=~"匹配,也可以用$&打印匹配的值。

第二:当且仅当循环中没有使用其他变量时,您应该使用 $_。循环中已经使用了$i,可以将循环编写为:

for my $i (2..9) {
  print "$in";
}

foreach(2..9) {
  print "$_n";
}

最新更新