Sascha Nehls: Regulärer Ausdruck um HTML zu filtern

Mittels dem Modul LWP::Simple lese ich den Inhalt einer Website (ich möchte letztendlich eine Fussballtabelle aus einer Website herausfilten), jedoch bekomme ich nicht den Inhalt des Bodys herausgelesen, also alles was zwischen <body ...> und </body> steht. Das Problem hierbei ist, dass in dem einleitenden Body-Tag viele Atribute stehe. Ich nutze den regulären Ausdruck .* dafür, aber es wird nichts zurückgeliefert?!

________
#!/usr/bin/perl -w
use strict;
use LWP::Simple;
my $html;

$html = get ("http://www.google.de");
$html =~ m/<body.*>(.*)</body>/si;  # Hier ist der Fehler versteckt

print "Content-type: text/html\n\n";
print "$1";
_________

  1. use Mosche;

    Mittels dem Modul LWP::Simple lese ich den Inhalt einer Website (ich möchte letztendlich eine Fussballtabelle aus einer Website herausfilten), jedoch bekomme ich nicht den Inhalt des Bodys herausgelesen, also alles was zwischen <body ...> und </body> steht. Das Problem hierbei ist, dass in dem einleitenden Body-Tag viele Atribute stehe. Ich nutze den regulären Ausdruck .* dafür, aber es wird nichts zurückgeliefert?!

    $html =~ m/<body.*>(.*)</body>/si;  # Hier ist der Fehler versteckt

    Ich gebe dir mal folgenden Quelltext:

    <body bgcolor="#456756"><h1>blah</h1></body>

    <body .*> macht jetzt auf "<body bgcolor="#456756"><h1>blah</h1>". Es würde hier also reichen, deinen Ausdruck zu so etwas umzuwandeln:
    /<body[^>]*>(.*)</body>/
    Problem könnte auftreten, wenn in einem Parameter ein '>' auftritt.

    Insgesamt ist es annähernd unmöglich, mit Regulären Ausdrücken HTML zu parsen. Nimm dafür einen dedizierten Parser wie HTML::Parser, erhältlich bei CPAN.

    use Tschoe qw(Matti);

    --
    neues Selftreffen?
    http://selfcommunity.teamone.de/foren/community/?t=2241&m=2687
      Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
  2. Hallo Sascha.

    $html =~ m/<body.*>(.*)</body>/si;  # Hier ist der Fehler versteckt

    Dein Ausdruck ist im untechnischen Sinne zu gierig. Wie dir Matti bereits antwortete, entspricht es deinem Suchmuster ".*", dass alles bis zum Ende erfasst wird, egal, was da steht. Ergo liefert dir "<body.*>" bereits den gesamten restlichen Inhalt, $1 muss also logischerweise leer sein. Du könntest diesen Fehler ausschließen, indem du ein genügsameres Suchmuster verwendest:

    http://selfhtml.teamone.de/cgiperl/sprache/regexpr.htm#gierig_genuegsam

    Also etwa so: "<body.+?>". Damit hättest du aber ein zweites Problem, denn der Klammerausdruck muss ja gierig sein, damit er alles bis zum Ende erfasst. Alles in allem deshalb auch von mir der Tipp, einen HTML-Parser zu verwenden, z.B. das bei Perl 5.8.0 standardmäßig verfügbare Modul HTML::Parser:

    http://www.perldoc.com/perl5.8.0/lib/HTML/Parser.html

    Grüße
    Siechfred