Extraer parte de una coincidencia de expresiones regulares


130

Quiero una expresión regular para extraer el título de una página HTML. Actualmente tengo esto:

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

¿Existe una expresión regular para extraer solo el contenido de <título> para que no tenga que eliminar las etiquetas?


55
wow, no puedo creer todas las respuestas que llaman a analizar toda la página HTML solo para extraer un título simple. ¡Qué exageración!
hoju

44
Título de la pregunta lo dice todo - el ejemplo dado pasa a ser HTML, pero el problema general es ... en general.
Phil

Respuestas:


207

Úselo ( )en regexp y group(1)en python para recuperar la cadena capturada ( re.searchse devolverá Nonesi no encuentra el resultado, así que no la use group()directamente ):

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

if title_search:
    title = title_search.group(1)

1
Si no está haciendo nada cuando no se encuentra ningún título, ¿por qué sería malo usar group () directamente? (De todos modos, puedes ver la excepción)
tonfa

1
sí, pero la mayoría de gente se olvida de excepciones, y están realmente sorprendidos cuando los ven en tiempo de ejecución :)
Krzysztof Krason

No te olvides de correr import reo de lo contrario obtendrásNameError: name 're' is not defined
Powers

16

Tenga en cuenta que al comenzar Python 3.8, y la introducción de expresiones de asignación (PEP 572) ( :=operador), es posible mejorar un poco la solución de Krzysztof Krasoń capturando el resultado del partido directamente dentro de la condición if como una variable y reutilizándolo en el cuerpo de la condición :

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

6

Intente usar grupos de captura:

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


4

¿Puedo recomendar a Beautiful Soup? La sopa es una muy buena lib para analizar todo su documento html.

soup = BeatifulSoup(html_doc)
titleName = soup.title.name

Me gustaría agregar que beautifulsoup también analiza html incompleto, y eso es realmente bueno.
hasta el

3

Tratar:

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

Si realmente desea utilizar REGEX para el análisis HTML, no ejecute .group () directamente en la coincidencia, ya que puede devolver Ninguno.
iElectric

Debe usarlo .*?en caso de que haya varios </title>en el documento (poco probable pero nunca se sabe).
tonfa

@ iElectric: puedes probarlo, excepto bloquear si realmente quieres, ¿verdad?
tonfa

3

Las piezas de código proporcionadas no cumplen con lo que Exceptions puedo sugerir.

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

Esto devuelve una cadena vacía por defecto si no se ha encontrado el patrón o la primera coincidencia.


1

Creo que esto debería ser suficiente:

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

... suponiendo que su texto (HTML) esté en una variable llamada "texto".

Esto también supone que no hay otras etiquetas HTML que se puedan incrustar legalmente dentro de una etiqueta de TÍTULO HTML y no hay forma de incrustar legalmente ningún otro carácter <dentro de dicho contenedor / bloque.

Sin embargo ...

No use expresiones regulares para el análisis HTML en Python. ¡Utiliza un analizador HTML! (A menos que vaya a escribir un analizador completo, lo que sería un trabajo adicional cuando varios analizadores HTML, SGML y XML ya están en las bibliotecas estándar.

Si maneja HTML de sopa de etiqueta del "mundo real" (que con frecuencia no se ajusta a ningún validador SGML / XML), utilice el paquete BeautifulSoup . No está en las bibliotecas estándar (todavía), pero se recomienda ampliamente para este propósito.

Otra opción es: lxml ... que está escrito para HTML correctamente estructurado (conforme a los estándares). Pero tiene una opción para recurrir al uso de BeautifulSoup como analizador: ElementSoup .

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.