重複した行が表示される理由は、配列全体をその中の要素ごとに 1 回印刷しているためです。
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
したがって、重複エラーを修正するには、2 番目のループを最初のループの外に移動します。
その他の注意事項:
次の 2 つのプラグマを常に使用する必要があります。
use strict;
use warnings;
彼らは、あなたができる他のどの単一のことよりも多くの助けを提供します. 表示されるエラーの修正に関連する短い学習曲線は、デバッグに費やされる大幅な時間の短縮を補って余りあります。
//my @list = $html->getElementsByTagName( "p" );
perl のコメントは で始まり#
ます。以下でこの配列を使用しているため、これがタイプミスかどうかはわかりません。
foreach my $elem ( @list ) {
配列が必要でない限り、実際にタグを配列に格納する必要はありません。これは、この場合のみの中間変数です。次のことを簡単に実行できます (for
とforeach
はまったく同じであることに注意してください)。
for my $elem ($html->getElementsByTagName("p")) {
これらの変数も中間であり、そのうちの 2 つは未使用です。
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;
ファイル ハンドルはスクリプトの終了時に自動的に閉じられるため、明示的に閉じる必要はありません。