Python RegEx pular os primeiros caracteres?
-
06-07-2019 - |
Pergunta
Ei, eu tenho uma pergunta bastante básico sobre expressões regulares. Quero apenas voltar dentro de texto (e incluindo) as etiquetas do corpo, e eu sei o seguinte não é certo, porque ele também vai corresponder a todos os caracteres antes do corpo tag de abertura. Eu queria saber como você faria para pular esses?
x = re.match('(.*<body).*?(</body>)', fileString)
Obrigado!
Solução
Aqui está um exemplo de código que usa regex para encontrar todo o texto entre as tags <body>...</body>
. Embora isso demonstra algumas características do módulo de re de python, nota que a módulo bonito Soup é muito fácil de usar e é uma ferramenta melhor para usar se você está pensando em análise de HTML ou XML. (Veja abaixo um exemplo de como você pode analisar isso usando BeautifulSoup.)
#!/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>
Se você deseja coletar todas as partidas, você poderia usar re.findall:
print(re.findall('(<body>.*?</body>)', fileString, re.DOTALL))
# ['<body>foo\nbaby foo\nbaby foo\nbaby foo\n</body>', '<body>bar</body>']
e se você planeja usar este padrão mais de uma vez, você pode pré-compilá-lo:
pat=re.compile('(<body>.*?</body>)', re.DOTALL)
print(pat.findall(fileString))
# ['<body>foo\nbaby foo\nbaby foo\nbaby foo\n</body>', '<body>bar</body>']
E aqui está como você pode fazê-lo com BeautifulSoup:
#!/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>]
Outras dicas
Eu não sei Python, mas aqui está um exemplo rápido jogado juntos usando bonito Soup , que muitas vezes eu vejo recomendado para análise Python HTML.
import BeautifulSoup
soup = BeautifulSoup(fileString)
bodyTag = soup.html.body.string
Essa vontade (em teoria) lidar com todas as complexidades do HTML, que é muito difícil com respostas baseadas em regex puros, porque não é o que regex foi projetado para.
Você não pode analisar HTML com regex. HTML não é uma linguagem regular. Use um analisador HTML como lxml vez.
x = re.match('.*(<body>.*?</body>)', fileString)
Considere minidom para HTML de análise.
x = re.search('(<body>.*</body>)', fileString)
x.group(1)
Menos digitação do que as respostas jogo
A sua fileString conter várias linhas ? Nesse caso, você pode precisar especificá-lo ou ignorar as linhas explicitamente:
x = re.match(r"(?:.|\n)*(<body>(?:.|\n)*</body>)", fileString)
ou, mais simplesmente com o módulo re:
x = re.match(r".*(<body>.*</body>)", fileString, re.DOTALL)
x.groups()[0]
deve conter a string se x não é None.