Günter Laudenklos: regexp Problemchen/Frage

Hallo Forum,
vor allem die PERL Chracks ;)

z.Zt.schreibe ich gerade ein kleines Script um HTML Dokumente auszulesen und aufzubereiten.
Bei einer kleinen Unterroutine stehe ich wohl etwas auf dem Schlauch ....
vielleicht sehe ich auch den Wald vor lauter Bäumen nicht mehr.

Problem ist das Auslesen von ALT= und TITLE= Parametern in HTML Tags:

----- snip ----

$_  enthält HTML Text-String , \n ist bereits entfernt.,

#                  ALT + TITLE Texte sollen in $stringa verkettet werden

while($_ =~ /<(.*?)>/igo)
{
$itag = $1;   # save inner TAG strings - umladen muss sein,
if($itag =~ / (?:alttitle)="(.*?)"/igo)     # da $1 ansonsten Mist enthält
{ $stringa .= "$1 " if($1); }  # join alt="any" oder title="thing" text-strings
}

----- snip ----

Das läuft auch so, aber ich wollte es noch etwas kürzer und habe folgendes geschrieben

---- snip ----

while($_ =~ /<(?:.*?\s+)(?:alttitle)="(.*?)"(?:.*>>)/igo) { $stringa .= "$1 " if($1); }

---- snip ---

das Resultat ist zwar das gleiche, die Verarbeitungszeit ging jedoch beim Schleifendurchlauf
über ca. 500 HTMLs drastisch in die Höhe..

Kann mir irgendjemand einen Tipp zur 2ten while Schleife geben?
Falls nicht, ist's zwar auch nicht schlimm, ich kann ja weiter die 1ste verwenden, aber
vielleicht habe ich ja als Perl-Laie was übersehen/nicht verstanden.

Viele Grüße  Günter

  1. Hallo Günter!

    ---- snip ----

    while($_ =~ /<(?:.*?\s+)(?:alttitle)="(.*?)"(?:.*>>)/igo) { $stringa .= "$1 " if($1); }

    ---- snip ---

    Ich hätte da folgendes Anzubieten:
    while($_ =~ /<[^>]+?\s+)(?:alttitle)="(.*?)"[^>]*>/igo) { $stringa .= "$1 " if($1); }

    Hauptsächlich sollte wohl die letzte Klammer bei Dir der Übeltäter sein. Der verwendete * ist ja bekanntlich "greedy" - also äußerst gefräßig! So schnappt er sich also erstmal den Gesamten Text und gibt ihn dann Zeichen für Zeichen wieder frei, bis eine Stelle gefunden ist, an der ein > folgt ...

    Probier es doch einfach mal aus. Schnellschuß bei Dir wäre dann ein ? einzubauen (?:.*?>>)

    Gruß,
       Jörk

    1. Hallo Jörk,

      Ich hätte da folgendes Anzubieten:
      while($_ =~ /<[^>]+?\s+)(?:alttitle)="(.*?)"[^>]*>/igo) { $stringa .= "$1 " if($1); }

      Hauptsächlich sollte wohl die letzte Klammer bei Dir der Übeltäter sein. Der verwendete * ist ja bekanntlich "greedy" - also äußerst gefräßig! So schnappt er sich also erstmal den Gesamten Text und gibt ihn dann Zeichen für Zeichen wieder frei, bis eine Stelle gefunden ist, an der ein > folgt ...

      Probier es doch einfach mal aus. Schnellschuß bei Dir wäre dann ein ? einzubauen (?:.*?>>)

      erstmal Danke für Deine Antwort, das scheint's aber noch nicht zu sein :(

      Dabei bekomme ich die Fehlermeldung
      "unmatched () in regexp at test.pl line xxx - ein Prozeß hat versucht, zu einer
      nicht bestehenden Pipe zu schreiben."

      Werde es trotzdem noch weiter probieren (und nachlesen, nachlesen ....)

      Vielen Dank + Grüße  Günter

      1. Hallo Jörk,

        Ich hätte da folgendes Anzubieten:
        while($_ =~ /<[^>]+?\s+)(?:alttitle)="(.*?)"[^>]*>/igo) { $stringa .= "$1 " if($1); }

        !
        und hier die Lösung - war eine Klammer zuviel bei Dir ...

        while($_ =~ /<[^>]+?\s+(?:alttitle)="(.*?)"[^>]*>/igo) { $stringa .= "$1 " if($1); }

        Vielen Dank,
        Günter

        (und wieder einmal hat sich dieses Forum aufs Beste bewährt)