Python RegEx Überspringen Sie die ersten Buchstaben?
-
06-07-2019 - |
Frage
Hey, ich habe eine ziemlich grundlegende Frage über reguläre Ausdrücke. Ich will nur den Text zurückkehren innen (einschließlich) der Body-Tags, und ich weiß, das folgende ist nicht richtig, weil es auch alle Zeichen vor der Eröffnung Body-Tag übereinstimmen werden. Ich habe mich gefragt, wie Sie über das Überspringen diejenigen gehen würde?
x = re.match('(.*<body).*?(</body>)', fileString)
Danke!
Lösung
Hier ist ein Beispiel-Code, der regex verwendet den gesamten Text zwischen <body>...</body>
-Tags zu finden. Obwohl dies einige Funktionen von Python re-Modul zeigt, beachten Sie, dass die Schöne Suppe Modul ein besseres Werkzeug zu verwenden, wenn Sie auf dem Parsen HTML- oder XML-Plan zu verwenden und ist sehr einfach. (Siehe unten für ein Beispiel, wie Sie dies mit BeautifulSoup analysieren könnten.)
#!/usr/bin/env python
import re
# Here we have a string with a multiline <body>...</body>
fileString='''baz<body>foo
baby foo
baby foo
baby foo
</body><body>bar</body>'''
# re.DOTALL tells re that '.' should match any character, including newlines.
x = re.search('(<body>.*?</body>)', fileString, re.DOTALL)
for match in x.groups():
print(match)
# <body>foo
# baby foo
# baby foo
# baby foo
# </body>
Wenn Sie alle Spiele sammeln möchten, können Sie re.findall verwenden:
print(re.findall('(<body>.*?</body>)', fileString, re.DOTALL))
# ['<body>foo\nbaby foo\nbaby foo\nbaby foo\n</body>', '<body>bar</body>']
und wenn Sie dieses Muster mehr verwenden möchten als einmal, können Sie vorab kompilieren:
pat=re.compile('(<body>.*?</body>)', re.DOTALL)
print(pat.findall(fileString))
# ['<body>foo\nbaby foo\nbaby foo\nbaby foo\n</body>', '<body>bar</body>']
Und hier ist, wie Sie es mit BeautifulSoup tun können:
#!/usr/bin/env python
from BeautifulSoup import BeautifulSoup
fileString='''baz<body>foo
baby foo
baby foo
baby foo
</body><body>bar</body>'''
soup = BeautifulSoup(fileString)
print(soup.body)
# <body>foo
# baby foo
# baby foo
# baby foo
# </body>
print(soup.findAll('body'))
# [<body>foo
# baby foo
# baby foo
# baby foo
# </body>, <body>bar</body>]
Andere Tipps
Ich weiß nicht, Python, aber hier ist ein kurzes Beispiel zusammen geworfen mit Schöner Suppe , die ich sehe oft für Python HTML-Analyse empfohlen.
import BeautifulSoup
soup = BeautifulSoup(fileString)
bodyTag = soup.html.body.string
Das wird (in der Theorie) befassen sich mit allen Komplexitäten von HTML, die mit reinen Regex-basierten Antworten sind sehr schwierig, weil es nicht, was regex ist wurde konzipiert.
Sie können nicht analysieren HTML mit regex. HTML ist keine reguläre Sprache. Verwenden Sie einen HTML-Parser wie lxml statt.
x = re.match('.*(<body>.*?</body>)', fileString)
Betrachten minidom für HTML-Analyse.
x = re.search('(<body>.*</body>)', fileString)
x.group(1)
Weniger Typisierung als die Spiel Antworten
Hat Ihr fileString enthalten mehrere Zeilen ? In diesem Fall müssen Sie es angeben, oder die Zeilen überspringen ausdrücklich:
x = re.match(r"(?:.|\n)*(<body>(?:.|\n)*</body>)", fileString)
oder einfach mit dem Re-Modul:
x = re.match(r".*(<body>.*</body>)", fileString, re.DOTALL)
x.groups()[0]
sollte die Zeichenfolge enthält, wenn x nicht None ist.