Seite 1 von 1

URLs mittels regex aus strings filtern [gelöst]

Verfasst: Montag 3. Dezember 2007, 14:11
von DonVla
hallo,

wie die überschrift schon beschreibt, möchte ich aus strings, wie z.b.:
'Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail'
oder
'uswsusp ( http://aur.archlinux.org/packages.php?d ... 1&ID=14093 )'
oder
'blabla bla bla sourceforge.net bla blub'
die URLs filtern, und dann natürlich auch als strings zurückgeben.
d.h. aus dem ersten string:
'http://www.gmx.net/de/go/freemail',
aus dem zweiten 'http://aur.archlinux.org/packages.php?d ... 1&ID=14093'
und aus dem dritten 'sourceforge.net'.

ich habe nun folgendes gemacht:

Code: Alles auswählen

grab_url = re.compile('(http(s)?://|ftp://)?(www\.)?[\w\.-]\.[a-z]{2,4}(/.*)?', re.I)
zur erklärung:
1. "(http(s)?://|ftp://)?" -> entweder http:// oder https:// oder ftp:// oder gar nichts
2. "(www\.)?" -> entweder www. oder gar nichts
3. "[\w\.-]" -> teil der URL zwischen www. und .domain, also [a-zA-Z0-9_] oder . oder - (hmm, hier wird der domain-teil doppelt erfasst...)
4. "\.[a-z]{2,4}" -> domain mit 2-4 zeichen (zb .de oder .info oder .org)
5. "(/.*)?" -> / am ende oder /irgenwelche zeichen oder gar nichts

ok, wenn ich das nun eingebe, passiert folgendes:

Code: Alles auswählen

>>> grab_url.findall('Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail')
[('', '', '', '')]

Code: Alles auswählen

>>> print grab_url.match('Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail')
None
oder

Code: Alles auswählen

>>> grab_url.findall('uswsusp ( http://aur.archlinux.org/packages.php?do_Details=1&ID=14093 )')
[('', '', '', ''), ('', '', '', '/packages.php?do_Details=1&ID=14093 )')]

Code: Alles auswählen

>>> print grab_url.match('uswsusp ( http://aur.archlinux.org/packages.php?do_Details=1&ID=14093 )')
None
heh? was zum geier mache ich falsch!!!
ich hing schon die halbe nacht dran, habe mich blöd gegooglet, aber irgendwie kriege ich das nicht hin.
bitte helft mir!

vlad

Re: URLs mittels regex aus strings filtern

Verfasst: Montag 3. Dezember 2007, 15:25
von Leonidas
DonVla hat geschrieben:heh? was zum geier mache ich falsch!!!
Ich denke der gesamte Ansatz ist falsch. Eine HTML-Seite mit Regulären Ausdrücken zu scrapen ist eher aufwendig, führt zu schwer verständlichem Code, kompliziert und bricht bei recht kleinen Änderungen der Seite. Nimm lieber eine Bibliothek die für Scraping gedacht ist, wie `BeautifulSoup` oder `html5lib`.

Verfasst: Montag 3. Dezember 2007, 15:33
von DonVla
hi,

danke für die antwort!
es ist eben keine html seite.
dann würde ich auch keine regex benutzen. es ist für ein imap-programm, dass den BODY[TEXT] der mail zeilenweise als string zuückgibt.
daraus möchte ich nun die links herausfiltern.

vlad

Verfasst: Montag 3. Dezember 2007, 15:38
von Leonidas
URLs mit Regulären Ausdrücken zu matchen ist nahezu unmöglich, der Versuch sieht etwa so aus.

Eine simple Regex wäre:

Code: Alles auswählen

(https?://[-A-Za-z/.?_=&0-9]*)
(ich habe den ganzen Ausdruck nochmal gruppiert, falls du innen noch Subgruppen verwenden willst).
Funktioniert natürlich nicht für alles und matcht auch nicht URLs. Aber URLs werden damit recht gut getroffen.

Verfasst: Montag 3. Dezember 2007, 15:47
von DonVla
danke Leonidas,

passt ganz gut!
muss es noch ein bißchen verfeinern, aber past schon sehr gut.
poste bald den (hoffentlich) funktionierenden ausdruck.

vlad

ps: noch eine frage:
im ausdruck (https?://[-A-Za-z/.?_=&0-9]*) bezieht sich das fragezeichen auf dem punkt (optional) oder meint dies das zeichen "?"?

Verfasst: Montag 3. Dezember 2007, 16:06
von BlackJack
Innerhalb der [] ist ein Fragezeichen einfach nur ein Fragezeichen ohne besondere Bedeutung.

Verfasst: Montag 3. Dezember 2007, 16:12
von DonVla
vielen dank an alle,

der aurduck sieht nun so aus:

Code: Alles auswählen

grab_url = re.compile(r'((https?://|ftp://|www\.)[-A-Za-z/.?_=&0-9#]*)', re.I)
und funktioniert gut.
ich hätte direkt fragen sollen. ich saß heute nacht bestimmt 4 stunden dran.

vlad

ps: underscore wird nicht angezeigt?
hier ausdruck nochmal ohne code-umgebung:
"grab_url = re.compile(r'((https?://|ftp://|www\.)[-A-Za-z/.?_=&0-9#]*)', re.I)"