我正在尝试阅读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
答案 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);