HTML mit RegEx filtern
Hallo, ich würde gerne in Python einen String manipulieren. HTML-Code soll dabei bereinigt bzw. umgewandelt werden: aus <img src='url' alt='irgendwas'> soll <img src='url'> werden. Das lässt sich prinzipiell mit dem RegEx Modul machen? Dazu fehlt mir noch die passende Expression... Hier komm ich gerade nicht weiter: string = re.sub(r"\&(.*?);", mat.group(0), text) Danke schon mal für Hilfe. Stefan.
Stefan Antonelli schrieb:
ich würde gerne in Python einen String manipulieren. HTML-Code soll dabei bereinigt bzw. umgewandelt werden:
aus <img src='url' alt='irgendwas'> soll <img src='url'> werden. [...]
Du willst aus einem W3C-konformen HTML-Tag einen nicht mehr konformen machen? *shrug* Gruß Florian
On Wednesday 20 December 2006 14:21, Stefan Antonelli wrote:
Hallo,
ich würde gerne in Python einen String manipulieren. HTML-Code soll dabei bereinigt bzw. umgewandelt werden:
aus <img src='url' alt='irgendwas'> soll <img src='url'> werden. Das lässt sich prinzipiell mit dem RegEx Modul machen?
Prinzipiell ja, aber es ist eine schlechte idee. Nimm stattdessen BeautifulSoup. Das Problem mit regulaeren Ausdruecken und HTML ist einfach, das sie immer komplizierter werden und immer mehr Spezialfaelle anhaeufen. Use the right tool for the job. Die
Diez B. Roggisch <deets@...> writes:
Prinzipiell ja, aber es ist eine schlechte idee. Nimm stattdessen BeautifulSoup.
Das Problem mit regulaeren Ausdruecken und HTML ist einfach, das sie immer komplizierter werden und immer mehr Spezialfaelle anhaeufen.
Klingt interessant - ich glaube das hab ich sogar schon mal in Action gesehen... Hast Du vielleicht ein oder zwei Links mit ein paar guten Tutorials? Ich finde zwar ne menge Links, aber eben kein gutes Tutorial. Trotzdem interessiert mich die RegularExpression um aus aus einem String einen Teil (wie im Beispiel die URL in src) zu übernehmen und in einen neuen String ein zu bauen? Ich bin immerhin schon so weit (bitte nicht kreuzigen): text = re.sub('<img src="(.*?)">', lambda mat: mat.group(1), text) Das filtert mir in einem String enthaltene Bilder heraus und gibt deren URLs zurück... Aber das muss doch schöner gehen? Und lambda ist an der Stelle doch eigentlich auch irgendwie weg zu kriegen? Stefan.
Stefan Antonelli schrieb:
Ich bin immerhin schon so weit (bitte nicht kreuzigen):
text = re.sub('<img src="(.*?)">', lambda mat: mat.group(1), text)
Das filtert mir in einem String enthaltene Bilder heraus und gibt deren URLs zurück... Aber das muss doch schöner gehen? Und lambda ist an der Stelle doch eigentlich auch irgendwie weg zu kriegen?
Reguläre Ausdrücke waren noch nie schön! ;-) Na klar, kannst du ohne lambda auskommen, definiere einfach eine richtige Funktion und gib deren Name als 2. Argument von re.sub an. Aber irgendeine Art von Callback brauchst du, so funktioniert die re.sub-Funktion nun mal. Besser wäre übrigens folgender Ausdruck: '(?i)<img .*?src="(.*?)".*?>' Dann können auch noch andere Attribute vor und nach 'src' kommen und die Tags dürfen auch in Großschreibung stehen. Aber daran siehst du schon, dass es mit regulären Ausdrücken irgendwann hässlich wird, wenn man alle Eventualitäten abdecken will (was dann meistens doch nicht gelingt). Chris
Stefan Antonelli schrieb:
Hast Du vielleicht ein oder zwei Links
Hi Stefan! Beispiele: http://www.python-forum.de/post-27658.html http://www.python-forum.de/post-37269.html#37269 #!/usr/bin/env python # -*- coding: iso-8859-1 -*- from BeautifulSoup import BeautifulSoup html = """<html> <head> <title>Hallo Welt</title> </head> <body> <img src="http://www.bcom.at/image1.gif"> <img src="http://www.bcom.at/image2.gif" /> <img srcccc="http://www.bcom.at/image3.gif" /> </body> </html> """ soup = BeautifulSoup(html) for image in soup("img"): try: print "src Methode1:", image["src"] except KeyError: print None print "src Methode2:", image.get("src") print "src Methode3:", dict(image.attrs).get("src") print mfg Gerold :-) -- ________________________________________________________________________ Gerold Penz - bcom - Programmierung gerold.penz@tirol.utanet.at | http://gerold.bcom.at | http://sw3.at Ehrliche, herzliche Begeisterung ist einer der wirksamsten Erfolgsfaktoren. Dale Carnegie
Klingt interessant - ich glaube das hab ich sogar schon mal in Action gesehen... Hast Du vielleicht ein oder zwei Links mit ein paar guten Tutorials? Ich finde zwar ne menge Links, aber eben kein gutes Tutorial.
Keine Ahnung - tutorials sind ja nett, API-docs & ein paar Beispiele reichen mir aber bei so etwas simplem.
Trotzdem interessiert mich die RegularExpression um aus aus einem String einen Teil (wie im Beispiel die URL in src) zu übernehmen und in einen neuen String ein zu bauen?
Ich bin immerhin schon so weit (bitte nicht kreuzigen):
text = re.sub('<img src="(.*?)">', lambda mat: mat.group(1), text)
Das filtert mir in einem String enthaltene Bilder heraus und gibt deren URLs zurück... Aber das muss doch schöner gehen? Und lambda ist an der Stelle doch eigentlich auch irgendwie weg zu kriegen?
Andere haben dir schon Loesungen gezeigt, die etwas weiter gehen. Aber was ist mit Attributen in einfachen Anfuehrungszeichen? Was ist (zugegeben, img-src hat das nicht) mit Attributen in denen das jeweils andere Anfuehrungszeichen vorkommt? Was mit Attributen, die gar keine Anfuehrungszeichen haben (HTML erlaubt das)? Was ist mit mehrzeiligen Tags? Was mit Gross/Kleinschreibung? Die Zeit die du investierst deinen RE wasserdicht zu machen, ist besser investiert sich mit BS und generell HTML/XML-parsing (so das geht, wenn der HTML-code ausreichend sauber ist) Glaub' es einfach. Es ist so. Diez
Diez B. Roggisch <deets@...> writes:
Keine Ahnung - tutorials sind ja nett, API-docs & ein paar Beispiele reichen mir aber bei so etwas simplem.
Vielleicht hätte ich dazu sagen sollen das ich relativer Newbie bin... Ich hab auf die schnelle einfach nichts gefunden das mir die Funktionen nahe bringt. Aber da ich das Thema mit Sicherheit noch einmal brauchen kann werde ich mir das bei Gelegenheit in Ruhe anschauen.
Andere haben dir schon Loesungen gezeigt, die etwas weiter gehen. Aber was ist mit Attributen in einfachen Anfuehrungszeichen? Was ist (zugegeben, img-src hat das nicht) mit Attributen in denen das jeweils andere Anfuehrungszeichen vorkommt? Was mit Attributen, die gar keine Anfuehrungszeichen haben (HTML erlaubt das)? Was ist mit mehrzeiligen Tags? Was mit Gross/Kleinschreibung?
Die Zeit die du investierst deinen RE wasserdicht zu machen, ist besser investiert sich mit BS und generell HTML/XML-parsing (so das geht, wenn der HTML-code ausreichend sauber ist)
Ja das glaub ich gerne und genau das bekomme ich auch zu spüren... Hier mein Vorschlag: text = re.sub(r'<img(.*?)>', lambda mat: mat.group(0).split(' ')[1][5:-1], text) Das dropped zumindest schon mal alles was an uninteressanten Attributen, verstümmelt oder konform, enthalten ist und gibt, sofern nach dem img auch die src folgt, die URL korrekt zurück.
On 21 Dez 2006, stefan.antonelli@operun.de wrote: [...]
Ja das glaub ich gerne und genau das bekomme ich auch zu spüren... Hier mein Vorschlag:
text = re.sub(r'<img(.*?)>', lambda mat: mat.group(0).split(' ')[1][5:-1], text)
Das dropped zumindest schon mal alles was an uninteressanten Attributen, verstümmelt oder konform, enthalten ist und gibt, sofern nach dem img auch die src folgt, die URL korrekt zurück.
Da sind noch einige Verbesserungsmöglichkeiten. Vor allem ist .* gierig; wenn in deinem String 2 Image-Tags nacheinander kommen paßt der Ausdruck auf beide. Wie wäre es mit: text = r"""<img src='foo' alt=bar> bla blub <img alt="dd" border=0 src="baz"><img src=foobar ""><img src=nochwasanderes '<' atrr="wert">""" reg = re.compile(r"""(?x) (<img\s+) # Ein img Tag (?: (src\s*=\s*['"]?[^'"]*['"]?) # src Attribut mit oder ohne Anführungszeichen # wir prüfen nicht ob sie passen |"[^"]*?" # oder ein Attribut in doppelten Anf. |'[^']*?' # oder in einfachen |[^'">] # oder etwas anderes )* # das ganze beliebig oft
""" # bis wir eine schließende spitze Klammer finden; ) reg.sub(r'\1\2>',text) # der Rückgabewert ist <img src='foo'> bla blub <img src="baz"><img src=foobar ><img src=nochwasanderes >
Ich bin mir nicht sicher, ob dies schon alle Sonderfälle abdeckt (wahrscheinlich eher nicht); du siehst, es geht, aber nicht trivial; angeregt zu obigem Konstrukt wurde ich übrigens durch ein Beispiel in Mastering Regular Expressions von Friedl (wenn man mit regexp arbeiten möchte/muß ist dies nahezu Pflichtlektüre). Karl
participants (6)
-
Christopher Arndt -
Diez B. Roggisch -
Florian Schlachter -
Gerold Penz -
khp@pflaesterer.de -
Stefan Antonelli