在具有正则表达式条件的循环中,Perl似乎不会重新进入循环

时间:2014-12-01 06:49:28

标签: regex perl

我正在尝试阅读diff文件,并将删除数据组(带有前导-<SPACE>)并添加数据库(领先+<SPACE>),我有以下内容,我想要的地方有一个内部while来读取所有删除或添加,但不知怎的,我看到在第一次匹配后,循环似乎重新评估,即之后一行符合32行上的条件,它进入循环,然后我将另一行读入$_,但控件转出循环到行36,而不是重新进入循环并再次检查条件! (我从调试器检查过)

 27 while (<$inh>) {
 28     next if /^$/;   
 29     next if /^[^-+]/;         # ignore non diff lines 
 30     chomp;
 31     my $tmps = '';
 32     while (/^\-\ /) {         # Read the entire block (all lines beginning with -<SPACE>
 33         $tmps .= getprintables($_);
 34         $_ = <$inh>;          # Read next line
 35     }
 36     push(@prevs, $tmps) if $tmps ne '';
 37     $tmps = '';
 38     while (/^\+\ /) {         # Read the entire block (all lines beginning with +<SPACE>
 39         $tmps .= getprintables($_);
 40         $_ = <$inh>;
 41     }
 42     push(@curs, $tmps) if $tmps ne '';
 43     $tmps = '';
 44 }
 45 close($inh);

我也尝试了较长的while ($_ =~ m/^\+\ /)形式但结果相同。我不知道这里有什么问题。我有Perl v5.14.2

1 个答案:

答案 0 :(得分:2)

我建议只从单个while循环中读取文件句柄,并使用状态变量执行其他逻辑。

如果我正确地阅读您的意图,您可以重新设计使用Range operator ..的方法,如下所示:

while (<$inh>) {
    next if /^$/;
    next if /^[^-+]/;    # ignore non diff lines
    chomp;

    if ( my $range = /^- / .. !/^- / ) {
        push @prevs, '' if $range == 1;
        $prevs[-1] .= getprintables($_) if $range !~ /E/;
    }

    if ( my $range = /^\+ / .. !/^\+ / ) {
        push @curs, '' if $range == 1;
        $curs[-1] .= getprintables($_) if $range !~ /E/;
    }
}

close($inh);