Perl变量不会保持设置,即使设置为"我们的"

时间:2016-01-29 18:52:18

标签: arrays perl loops variables global

我有一个文件,我希望搜索字符串,与存储在数组中的项匹配。我打开文件,循环浏览它,当我找到我正在寻找的东西时,我改变了一个变量标志,这样就可以完成额外的工作。我有一个问题,我设置的变量不坚持。我将变量放在foreach循环中,使其成为our变量,但无济于事。

可疑代码:

my $zed = 0;
foreach my $SUB (@sub) {
    print "We are currently looking for $SUB<br><br>";

    open (my $input, "<", "C:\\Users\\scottbro\\Desktop\\PMS.txt")
        or die "Cannot open PMS.txt: $!";

    our $flag = 0;
    ##SET Zed to keep track of where we are
    print "Zed is $zed<br>Flag is $flag<br>";
    $zed++;

    while (<$input>) {

        print "inside the while loop, flag is now $flag<br>";
        ##  IF you find what you are looking for, set flag to 1
        if (/$SUB/) {
            $flag = 1;
            print "Found sub property, flag is now $flag<br>";
            ## IF flag is 1, and line has email address, show it!
        } elsif ($flag = 1 && /<email>(.+)/) {
            print "Flag is $flag, email is $1<br>";
        }

    }
    close($input);
}

输出,可以看到标志变量丢失值:

We are currently looking for Property 1
Zed is 0
Flag is 0
inside the while loop, flag is now 0
inside the while loop, flag is now 
Flag is 1, email is email1
inside the while loop, flag is now 1
Flag is 1, email is email2
inside the while loop, flag is now 1
inside the while loop, flag is now 
inside the while loop, flag is now 
inside the while loop, flag is now 
Found sub property, flag is now 1
inside the while loop, flag is now 1
Flag is 1, email is email3
inside the while loop, flag is now 1
Flag is 1, email is email4
inside the while loop, flag is now 1
inside the while loop, flag is now 
inside the while loop, flag is now 
Flag is 1, email is email 5

2 个答案:

答案 0 :(得分:4)

在测试

中将分配给$flag
elsif  (  $flag=1 && /<email>(.+)/ ) {  ... }
如果正则表达式模式不匹配,

$flag设置为1 && /<email>(.+)/ false

应该是

if  (  $flag and /<email>(.+)/ ) { ... }


我建议您忘记$flag,而是使用输入文件如果找不到$sub则为eof的事实,因此程序将无法再读取任何内容反正

回放文件而不是重新打开文件也更好。几乎可以肯定的是,数据应该被解析为一个哈希并直接访问,但是我无法确定您提供的信息

my @sub;

open my $fh, '<', 'C:\Users\scottbro\Desktop\PMS.txt' or die "Cannot open PMS.txt: $!";

for my $sub ( @sub ) {

    seek $fh, 0, 0;

    while ( <$fh> ) {
        last if /$sub/;
    }

    while ( <$fh> ) {
        next unless /<email>(.+)/;
        print qq{Email for "$sub" is "$1"};
        last;
    }
}

答案 1 :(得分:-2)

您要在测试中分配$flag而不是检查其值。

elsif ($flag = 1 && /<email>(.+)/)

应该是

elsif ($flag == 1 && /<email>(.+)/)

甚至更好,

elsif ($flag && /<email>(.+)/)

也就是说,反复阅读同一个文件是非常低效的。这是一个没有的版本。

my $pat = join '|', map quotemeta, @subs;

my $qfn = 'C:\\Users\\scottbro\\Desktop\\PMS.txt';
open(my $fh, '<', $qfn)
   or die(qq{"Can't open "$qfn": $!\n"});

while (<$fh>) {
   my ($sub) = /($pat)/
      or next;

   defined( $_ = <$fh> )
      or last;

   my ($email) = /<email>(.+)/
      or redo;

   print(qq{Email for "$sub" is "$email"\n});
}