1

このコード:

#!/bin/perl

BEGIN { $/ = undef; };
open (FILE,"file.txt") ||  die "Cannot open $FILE:$!";

while (<FILE>) {
    my @matches;

    if  ( m#SelectEditPolicy\.do\?policyID=[0-9]{1,4}.*?">(.*?)</a>#sg) {
        push (@matches,$1);
    }

    foreach $rec (@matches) {
        print "$rec\n";
    }
}   

このファイルに対して:

>cat file.txt
SelectEditPolicy.do?policyID=2958')">
Test123  OLD</a>
SelectEditPolicy.do?policyID=6643')">
Test123 </a>

file.pl を実行すると、最初の一致のみが返されます。できるだけ多くの投稿を読みましたが、成功はありませんか?

私は何を間違っていますか?

4

1 に答える 1

1

あなたはかなり多くのことを間違っています。最初に突き出ているのは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') };
}
于 2012-11-14T03:46:31.577 に答える