1

私はPerlの専門家ではありませんが、HTMLページを解析してすべてのhrefタグでフィルタリングするPerlスクリプトを作成しました。

出力は次のとおりです。

href="?Name">Name</a>
href="?Desc">Hourly Details</a>
href="/24x7/2012/11-November/">Data
href="./00:00:00/">00:00:00/</a>
href="./01:00:00/">01:00:00/</a>
href="./02:00:00/">02:00:00/</a>
href="./03:00:00/">03:00:00/</a>
href="./04:00:00/">04:00:00/</a>
href="./05:00:00/">05:00:00/</a>
href="./06:00:00/">06:00:00/</a>
href="./07:00:00/">07:00:00/</a>
href="./08:00:00/">08:00:00/</a>
href="./09:00:00/">09:00:00/</a>
href="./10:00:00/">10:00:00/</a>
href="./11:00:00/">11:00:00/</a>
href="./12:00:00/">12:00:00/</a>
href="./13:00:00/">13:00:00/</a>
href="./14:00:00/">14:00:00/</a>
href="./15:00:00/">15:00:00/</a>
href="./16:00:00/">16:00:00/</a>
href="./17:00:00/">17:00:00/</a>
href="./18:00:00/">18:00:00/</a>
href="./19:00:00/">19:00:00/</a>
href="./20:00:00/">20:00:00/</a>
href="./21:00:00/">21:00:00/</a>
href="./22:00:00/">22:00:00/</a>
href="./23:00:00/">23:00:00/</a>

ここで、hrefタグ内の値を「00:00:00」から「23:00:00」まで抽出し、他の値は除外します。結果の値は、URLを持つ文字列に追加されます。

http://x.download.com/00:00:00
------URL------------/..href../
..............................
http://x.download.com/23:00:00

ただし、以下のコードを試してみてください。

foreach (@tag) {
    if (m/href/) {
        if ($_ =~ /"\/24/ && $_ =~ /"\/[0-9]/) {
            my $href  = $_;
            my $start = index($href, "\"");
            my $end   = rindex($href, "\"");
            my $link  = substr($href, $start + 1, $end - $start - 1);
            print "Follow: " . $url . $link . "\n";

        }
    }
}

プリント:

Follow: http://x.download.com/24x7/2012/11-November/

必要な目的を達成できるように、私の正規表現は何である必要がありますか?

4

3 に答える 3

3

これは、以下のプログラムに示すように、正規表現を使用して非常に簡単に実行されます。直後の数字またはコロンの文字列を検索し>(したがって、属性値ではなく要素のテキストコンテンツを検索しますhref)、その文字列をにキャプチャします$1

HTML::TreeBuilder ただし、または などの適切なHTMLパーサーを使用して、問題が最初から最後まで解決されることを確認したいと思います Mojo::DOM

use strict;
use warnings;

my @tag = <DATA>;

foreach (@tag) {
  next unless />([\d:]+)/;
  print "http://x.download.com/$1\n";
}

__DATA__
href="?Name">Name</a>
href="?Desc">Hourly Details</a>
href="/24x7/2012/11-November/">Data
href="./00:00:00/">00:00:00/</a>
href="./01:00:00/">01:00:00/</a>
href="./02:00:00/">02:00:00/</a>
href="./03:00:00/">03:00:00/</a>
href="./04:00:00/">04:00:00/</a>
href="./05:00:00/">05:00:00/</a>
href="./06:00:00/">06:00:00/</a>
href="./07:00:00/">07:00:00/</a>
href="./08:00:00/">08:00:00/</a>
href="./09:00:00/">09:00:00/</a>
href="./10:00:00/">10:00:00/</a>

出力

http://x.download.com/00:00:00
http://x.download.com/01:00:00
http://x.download.com/02:00:00
http://x.download.com/03:00:00
http://x.download.com/04:00:00
http://x.download.com/05:00:00
http://x.download.com/06:00:00
http://x.download.com/07:00:00
http://x.download.com/08:00:00
http://x.download.com/09:00:00
http://x.download.com/10:00:00
于 2012-11-27T13:44:39.903 に答える
3

正規表現でそれをしたくありません。適切なHTMLパーサーが必要であり、正規表現はその役割を果たしません。

Webページをどのように取得していますか?WWW :: Mechanizeを使用している場合、WWW :: MechanizeがHTML解析を行うため、フェッチしたページからリンクを抽出するのは1つのメソッド呼び出しです。

use WWW::Mechanize;

my $mech = WWW::Mechanize->new();
$mech->get( $url );

my @links = $mech->links();
for my $link ( @links ) {
    say $link->text, ' -> ', $link->url; # Show the text and the URL
}

必要に応じて再フォーマットする必要がありますが、それでアイデアが得られます。

于 2012-11-27T13:54:50.740 に答える
0

まず、軍事時間を秒単位でキャプチャする正規表現を指定する必要があります。

my $regex 
    = qr{  # curly brackets instead of slashes
           # so that we can use literal slashes in expression

    "   # a quote
    \.  # a literal dot
    /   # a forward slash
    (   # begin capture group

       (?:              # begin uncaptured sub-group
           [01] \d      # a '0' or '1' followed by a digit
       |   2    [0-3]   # a '2' followed by 0-3
       )                # end grouping
       (?:         # begin repetition grouping
         :         # a literal colon               
         [0-5] \d  # digits 0-5 followed by any digit
       ){2}        # exactly twice
     )  # end capture

     /  # a forward slash
     "  # close quote
}x; # <- x-option allows annotated regex
...

これは、次の正規表現と同等です。

my $regex = qr/"\.\/((?:[01]\d|2[0-3])(:[0-5]\d){2})\/"/;

分と秒が「00:00」になるだけの場合、式はさらに簡単になります。

my $regex = qr{"\./((?:[01]\d|2[0-3]):00:00)/"};

次に、リストコンテキストで一致させることにより、値をテストおよび取得できます。

if ( my ( $link ) = m/$regex/ ) { 
    say "http://x.download.com/$link";
}

テストが一致しない場合、は$link未定義になります。一致する場合は、(1つの)リストとして宣言すると、一致操作によって最初のキャプチャが変数に割り当てられます。

于 2012-11-27T13:45:16.920 に答える