あなたはかなり多くのことを間違っています。最初に突き出ているのはBEGIN { $/ = undef; };
、ファイルを丸呑みする場合$/ = undef
は、適用可能な最小の範囲に設定します。さらに、ファイルを丸呑みすることに決めたら、while
それを行ごとに読み取るふりをしてループを使用する理由はありません。
第二に、HTML ファイルに前処理を行って、正規表現を適用できる形式に縮小したようです。HTML::TokeParser::Simpleのようなものを使用することで、あなたの生活はより楽になったでしょう。
#!/usr/bin/env perl
use strict;
use warnings;
my $content = do { local $/; <DATA> };
my @matches = ($content =~ m{
SelectEditPolicy\.do\?
policyID=[0-9]{1,4}[^>]*?">
([^<]*?)
</a>
}xsg );
print "$_\n" for @matches;
__DATA__
SelectEditPolicy.do?policyID=2958')">
Test123 OLD</a>
SelectEditPolicy.do?policyID=6643')">
Test123 </a>
出力:
Test123 OLD
テスト123
元の HTML でHTML::TokeParser::Simpleを使用すると、次のようなことを行った可能性があります (未テスト):
#!/usr/bin/env perl
use strict;
use warnings;
use HTML::TokeParser::Simple;
my $parser = HTML::TokeParser::Simple->new(url => 'http://example.com/');
my @policies;
while (my $tag = $parser->get_tag('a')) {
my $href = $tag->get_attr('href');
next unless defined $href;
next unless $href =~ /SelectEditPolicy\.do\?policyID=([0-9]{1,4})/;
push @policies, { $1 => $parser->get_text('/a') };
}