2016-04-16 8 views
-3

Angenommen, ich habe die folgende Zeichenfolge:findall() Verhalten (Python 2.7)

"<p>Hello</p>NOT<p>World</p>" 

und ich möchte, um die Worte extrahieren Hello und World

ich das folgende Skript für den Job erstellt

#!/usr/bin/env python 

import re 

string = "<p>Hello</p>NOT<p>World</p>" 
match = re.findall(r"(<p>[\w\W]+</p>)", string) 

print match 

Ich bin nicht besonders daran interessiert, < p> und </p> zu strippen, also habe ich es nie im Skript getan.

Die Dolmetscher drucken

so sieht es offenbar die ersten < p> und die letzten </p>, während die zwischen Tags zu vernachlässigen. Sollte nicht findall() alle drei Sätze der übereinstimmenden Zeichenketten obwohl zurückgeben? (die Zeichenkette, die es druckt, und die zwei Wörter).

Und wenn nicht, wie kann ich den Code ändern, um dies zu tun?

PS: Dies ist für ein Projekt und ich fand eine alternative Art und Weise zu tun, was ich brauchte, um, so ist dies aus pädagogischen Gründen, denke ich.

+1

http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags – BrenBarn

Antwort

1

Der Grund, dass Sie den gesamten Inhalt in einem Einzelspiel bekommen, weil [\w\W]+so viele Dinge übereinstimmen, wie es kann (alle Ihre <p> und </p> Tags einschließlich). Um dies zu verhindern, möchten Sie die nicht-gierige Version verwenden, indem Sie eine ? anhängen.

match = re.findall(r"(<p>[\w\W]+?</p>)", string) 
# ['<p>Hello</p>', '<p>World</p>'] 

Vom documentation:

*?, +?, ??
Die '*', '+' und '?'-Qualifikation sind alle gierig; Sie stimmen so viel Text wie möglich ab. Manchmal ist dieses Verhalten nicht erwünscht; Wenn der RE <.*> mit <a> b <c> verglichen wird, wird die gesamte Zeichenfolge übereinstimmen und nicht nur <a>. Das Hinzufügen von ? nach dem Qualifikationsmerkmal bewirkt, dass es die Übereinstimmung in nicht gieriger oder minimaler Weise durchführt; so wenige Zeichen wie möglich werden übereinstimmen. Die Verwendung des RE <.*?> entspricht nur <a>.

Wenn Sie nicht die <p> und </p> Tags im Ergebnis wollen, mögen Sie Vorgriff verwenden und hinter Behauptungen schauen, um sie nicht im Ergebnis enthalten. obwohl

match = re.findall(r"((?<=<p>)\w+?(?=</p>))", string) 
# ['Hello', 'World'] 

als eine Randnotiz, wenn Sie versuchen, HTML oder XML mit regulären Ausdrücken zu analysieren, ist es vorzuziehen, eine Bibliothek wie BeautifulSoup zu verwenden, die für das Parsen von HTML gedacht.

+0

Vielen Dank. Ich glaube, ich habe diesen Teil von REs übersehen – persongr

+0

Ich werde auch in BeautifulSoup schauen, danke für den Vorschlag. – persongr

+0

+1 für BeautifulSoup (oder ähnlich). HTML ist keine reguläre Sprache, daher sind reguläre Ausdrücke kein gutes Werkzeug, um sie zu analysieren. Es wird viel einfacher sein, eine Bibliothek zu verwenden, die HTML versteht. – nighthawk454