Extrair parte de uma correspondência de regex

130

Eu quero uma expressão regular para extrair o título de uma página HTML. Atualmente eu tenho isso:

title = re.search('<title>.*</title>', html, re.IGNORECASE).group()
if title:
    title = title.replace('<title>', '').replace('</title>', '') 

Existe uma expressão regular para extrair apenas o conteúdo de <title>, para que eu não precise remover as tags?

hoju
fonte
5
uau Não acredito em todas as respostas que chamam para analisar a página HTML inteira apenas para extrair um título simples. Que exagero!
hoju 27/08/2009
4
Título da pergunta diz tudo - o exemplo dado acontece a ser HTML, mas o problema geral é ... geral.
Phil

Respostas:

207

Use ( )no regexp e group(1)no python para recuperar a string capturada ( re.searchretornará Nonese não encontrar o resultado, portanto , não use group()diretamente ):

title_search = re.search('<title>(.*)</title>', html, re.IGNORECASE)

if title_search:
    title = title_search.group(1)
Krzysztof Krasoń
fonte
1
Se você não está fazendo nada quando nenhum título é encontrado, por que seria ruim usar o group () diretamente? (você pode pegar o de qualquer maneira exceção)
tonfa
1
Sim, mas a maioria das pessoas esquecer-se sobre exceções, e estão realmente surpreso quando vê-los em tempo de execução :)
Krzysztof Krason
Não se esqueça de correr, import reou então você teráNameError: name 're' is not defined
Powers
16

Observe que o início Python 3.8e a introdução de expressões de atribuição (PEP 572) ( :=operador), é possível melhorar um pouco a solução de Krzysztof Krasoń capturando o resultado da partida diretamente dentro da condição if como uma variável e reutilizá-lo no corpo da condição :

# pattern = '<title>(.*)</title>'
# text = '<title>hello</title>'
if match := re.search(pattern, text, re.IGNORECASE):
  title = match.group(1)
# hello
Xavier Guihot
fonte
6

Tente usar grupos de captura:

title = re.search('<title>(.*)</title>', html, re.IGNORECASE).group(1)
Aaron Maenpaa
fonte
5
re.search('<title>(.*)</title>', s, re.IGNORECASE).group(1)
Vinay Sajip
fonte
4

Posso recomendar-lhe a sopa bonita. Soup é uma lib muito boa para analisar todo o seu documento html.

soup = BeatifulSoup(html_doc)
titleName = soup.title.name
Kharagpur
fonte
Gostaria de acrescentar que beautifulsoup também analisa html incompleto, e isso é muito bom.
End-
3

Experimentar:

title = re.search('<title>(.*)</title>', html, re.IGNORECASE).group(1)
Randy
fonte
Se você realmente deseja usar o REGEX para análise de HTML, não execute .group () diretamente na correspondência, pois pode retornar Nenhum.
iElectric
Você deve usá- .*?lo caso haja vários </title>no documento (improvável, mas você nunca sabe).
tonfa
@iElectric: você pode experimentá-lo, exceto o bloco, se realmente quiser, certo?
25210 tonfa
3

Os trechos de código fornecidos não lidam com Exceptions Posso sugerir

getattr(re.search(r"<title>(.*)</title>", s, re.IGNORECASE), 'groups', lambda:[u""])()[0]

Isso retorna uma sequência vazia por padrão, se o padrão não foi encontrado ou a primeira correspondência.

Steve K
fonte
1

Eu acho que isso deve ser suficiente:

#!python
import re
pattern = re.compile(r'<title>([^<]*)</title>', re.MULTILINE|re.IGNORECASE)
pattern.search(text)

... assumindo que seu texto (HTML) esteja em uma variável chamada "texto".

Isso também pressupõe que não há outras tags HTML que possam ser legalmente incorporadas dentro de uma tag HTML TITLE e que não há maneira de incorporar legalmente qualquer outro caractere <dentro desse contêiner / bloco.

No entanto ...

Não use expressões regulares para análise de HTML no Python. Use um analisador de HTML! (A menos que você escreva um analisador completo, o que seria um trabalho extra quando vários analisadores de HTML, SGML e XML já estiverem nas bibliotecas padrão.

Se você manipular o HTML de sopa de tags do "mundo real" (que geralmente não está em conformidade com qualquer validador SGML / XML), use o pacote BeautifulSoup . Ainda não está nas bibliotecas padrão, mas é amplamente recomendado para esse fim.

Outra opção é: lxml ... que é escrito para HTML adequadamente estruturado (conforme os padrões). Mas tem uma opção para usar o BeautifulSoup como um analisador: ElementSoup .

Jim Dennis
fonte