2010-04-10 4 views
8

Beim Versuch, den Titel einer HTML-Seite zu extrahiert Ich habe immer die folgende regex verwendet:Python Regex Blick hinter erfordert festes Breite Muster

(?<=<title.*>)([\s\S]*)(?=</title>) 

, die alles zwischen den Tags in einem Dokument extrahieren und Ignoriere die Tags selbst. Wenn jedoch diese Regex in Python zu verwenden versucht, stellt sich die folgende Ausnahme:

Traceback (most recent call last): 
File "test.py", line 21, in <module> 
    pattern = re.compile('(?<=<title.*>)([\s\S]*)(?=</title>)') 
File "C:\Python31\lib\re.py", line 205, in compile 
    return _compile(pattern, flags) 
File "C:\Python31\lib\re.py", line 273, in _compile 
    p = sre_compile.compile(pattern, flags) File 
"C:\Python31\lib\sre_compile.py", line 495, in compile 
    code = _code(p, flags) File "C:\Python31\lib\sre_compile.py", line 480, in _code 
_compile(code, p.data, flags) File "C:\Python31\lib\sre_compile.py", line 115, in _compile 
    raise error("look-behind requires fixed-width pattern") 
sre_constants.error: look-behind requires fixed-width pattern 

Der Code ich verwende ist:

pattern = re.compile('(?<=<title.*>)([\s\S]*)(?=</title>)') 
m = pattern.search(f) 

, wenn ich einige minimale Anpassungen machen es funktioniert:

pattern = re.compile('(?<=<title>)([\s\S]*)(?=</title>)') 
m = pattern.search(f) 

Dies berücksichtigt jedoch nicht mögliche HTML-Titel, die aus irgendeinem Grund Attribute oder ähnliches haben.

Wer weiß eine gute Abhilfe für dieses Problem? Irgendwelche Tipps werden geschätzt.

+0

Gibt es einen Grund, warum es eine Assertion mit der Breite null sein muss? Könnten Sie einfach eine nicht einfangende Gruppe verwenden? –

+3

Obwohl Sie keine regulären Ausdrücke verwenden sollten, um HTML zu verarbeiten. Warum benutzen Sie überhaupt Umschau und nicht so etwas wie ' ([\ s \ S] *)' und nehmen Sie das Spiel der ersten Gruppe? – Gumbo

Antwort

1

Wenn Sie nur den Titel-Tag erhalten möchten,

html=urllib2.urlopen("http://somewhere").read() 
for item in html.split("</title>"): 
    if "<title>" in item: 
     print item[ item.find("<title>")+7: ] 
10

Verwerfen Sie die Idee, HTML mit regulären Ausdrücken zu analysieren, und verwenden Sie stattdessen eine tatsächliche HTML-Parsing-Bibliothek. Nach einer schnellen Suche fand ich this one. Es ist eine viel sicherere Möglichkeit, Informationen aus einer HTML-Datei zu extrahieren.

Denken Sie daran, HTML ist keine reguläre Sprache, daher sind reguläre Ausdrücke grundsätzlich das falsche Werkzeug, um Informationen daraus zu extrahieren.

+6

BeautifulSoup (http://www.crummy.com/software/BeautifulSoup/) ist auch eine gute Option. –

5

Here's a famous answer beim Parsing von HTML mit regulären Ausdrücken, die eine gute Arbeit zu sagen, "Verwenden Sie keine Regex zum Parsen von HTML."

+4

Ja und nein. Sie sollten Regex nicht verwenden, um ein gesamtes DOM oder komplizierte Verschachtelung von Tags zu analysieren. Das Analysieren eines einzelnen nicht verschachtelten Tags, wie es das OP versucht, ist jedoch eine vollkommen legitime Verwendung von Regex. – Cerin

2

Was ist so etwas wie:

r = re.compile("(<title.*>)([\s\S]*)(</title>)") 
title = r.search(page).group(2) 
3

Die Regex den Inhalt von nicht-verschachtelten HTML zum Extrahieren/XML-Tags ist sehr tatsächlich simple:

Aber für etwas komplexer, sollten Sie wirklich einen richtigen DOM-Parser wie Urlli verwenden b oder BeautifulSoup.