您看到重复行的原因是您为其中的每个元素打印整个数组一次。
foreach my $elem ( @list ) {
my $tagname = $elem->tagName;
my $attr = $elem->attributes;
my $text = $elem->innerText;
push (@array,"$text"); # this array is printed below
foreach $_ (@array) { # This is inside the other loop
# print "$_\n";
print $html_fh "$_\n"; # here comes the print
chomp ($_);
push (@array1, "$_");
}
}
例如,如果你有一个数组"foo", "bar", "baz"
,它会打印:
foo # first iteration
foo # second
bar
foo # third
bar
baz
因此,要修复您的重复错误,请将第二个循环移到第一个循环之外。
其他一些注意事项:
您应该始终使用这两个编译指示:
use strict;
use warnings;
他们将提供比您可以做的任何其他单一事情更多的帮助。与修复出现的错误相关的较短的学习曲线足以弥补大量减少的调试时间。
//my @list = $html->getElementsByTagName( "p" );
perl 中的注释以#
. 不确定这是否是一个错字,因为您在下面使用了这个数组。
foreach my $elem ( @list ) {
除非您需要数组,否则您不需要将标签实际存储到数组中。这仅在这种情况下是一个中间变量。您可以简单地执行以下操作(注意for
和foreach
完全相同):
for my $elem ($html->getElementsByTagName("p")) {
这些变量也是中间变量,其中两个未使用。
my $tagname = $elem->tagName;
my $attr = $elem->attributes;
my $text = $elem->innerText;
push (@array,"$text");
另请注意,您永远不必以这种方式引用变量。你可以简单地这样做:
push @array, $elem->innerText;
foreach $_ (@array) {
该$_
变量默认使用,无需显式指定。
print $html_fh "$_\n";
chomp ($_);
push (@array1, "$_");
我不确定为什么在打印变量之后chomp
,但在将其存储在另一个数组中之前,为什么要对变量进行ing ,但这对我来说似乎没有意义。此外,这个另一个数组将包含与另一个数组完全相同的元素,只是重复。
$end = $#array1+1;
这是另一个中间变量,也可以简化。$#
印记会给你最后一个元素的索引,但是标量上下文中的数组本身会给你它的大小:
$end = @array1; # size = last index + 1
但是你可以一口气做到这一点:
print "Elements in the array: " . @array1 . "\n";
请注意,.
此处使用连接运算符会在数组上强制执行标量上下文。如果您使用了逗号运算符,
,它将具有列表上下文,并且该数组将被扩展为其元素的列表。这是根据上下文进行操作的典型方式。
close $html_fh;
不需要显式关闭文件句柄,因为它会在脚本结束时自动关闭。