regexp Problemchen/Frage
Günter Laudenklos
- perl
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 ----
# 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
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
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
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)