我需要在找到第一个匹配后退出循环并转到循环中的另一个搜索
use strict;
use warnings;
my %iptv;
sub trim($) {
my $string = shift;
$string =~ s/\r\n//g;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
my @files=</tests/*>;
open IN, "/20131105.csv";
LINE: while (<IN>) {
chomp;
my @result = split(/;/,$_);
my $result1 = trim($_);
$result[1] = trim($result[1]);
$iptv{$result[1]} = $result1;
}
close IN;
foreach my $file (@files) {
open FILE, "$file";
while (<FILE>) {
chomp;
my ($mac, $date) = split(/;/,$_);
my @date1 = split(/\s/, $date);
print "$iptv{$mac};$date1[0]\n" if defined $iptv{$mac};
last LINE if (defined $iptv{$mac});
}
close FILE;
}
我尝试使用“最后”功能,但它找到第一个匹配并结束程序。我必须放在哪里?
答案 0 :(得分:1)
让我们看一下文档:
$ perldoc -f last
last LABEL
last The "last" command is like the "break" statement in C (as used
in loops); it immediately exits the loop in question. If the
LABEL is omitted, the command refers to the innermost enclosing
loop. The "continue" block, if any, is not executed:
LINE: while (<STDIN>) {
last LINE if /^$/; # exit when done with header
#...
}
"last" cannot be used to exit a block that returns a value such
as "eval {}", "sub {}" or "do {}", and should not be used to
exit a grep() or map() operation.
Note that a block by itself is semantically identical to a loop
that executes once. Thus "last" can be used to effect an early
exit out of such a block.
See also "continue" for an illustration of how "last", "next",
and "redo" work.
我们可以在这里清楚地了解如何使用last
。如果省略标签,则会突破最里面的循环。因此,只有在我们不希望这样做的情况下,我们才会使用标签。你想要这个,所以你不需要标签。
关于您的代码的一些注意事项:
检查open
的返回值,并使用三个带有词法文件句柄的参数。
open my $fh, "<", $file or die "Cannot open $file: $!";
这也有一个好处,当词法变量$fh
超出范围时,文件句柄将被关闭。
当您在\s
上拆分时,您会拆分一个空格。大多数情况下,这不是你想要的。例如,如果你有一个日期,如
$str = "Jan 1 2013" # (note the two consecutive spaces)
...这将分成列表"Jan", "", "1", "2013"
(注意空字段)。如果空字段是相关的,例如使用类似csv的数据,这只是你想要的。 split
的默认行为使用' '
(空格字符),其行为类似/\s+/
,但它也会删除前导空格。
请注意,此循环中的最后两个语句可以合并。此外,不需要使用临时数组@date1
。所以你的代码看起来像:
open my $fh, "<", $file or die "Cannot open $file: $!";
while (<$fh>) {
chomp;
my ($mac, $date) = split /;/, $_;
($date) = split ' ', $date;
if (defined $iptv{$mac}) {
print "$iptv{$mac};$date\n" ;
last;
}
}
答案 1 :(得分:0)
foreach my $file (@files) {
open FILE, "$file";
LINE: while (<FILE>) {
chomp;
my ($mac, $date) = split(/;/,$_);
my @date1 = split(/\s/, $date);
print "$iptv{$mac};$date1[0]\n" if defined $iptv{$mac};
last LINE if (defined $iptv{$mac});
}
close FILE;
}
应该确保你只退出内循环。
我想如果你完全摆脱last
背后的LINE标签,它也可以正常工作,但我建议总是使用带有last
的标签,以确保它没有做出意想不到的事情。如果你添加了一个额外的内部循环而忘记了last
,你希望在外面留一个更远的循环。