Problema con expresiones regulares en python

Ok, entonces estoy trabajando en una expresión regular para buscar toda la información del encabezado en un sitio.

He comstackdo la expresión regular:

regex = re.compile(r''' \s? ()?\s? [A-Za-z0-9.,:'"=/?;\s]*\s? [A-Za-z0-9.,:'"=/?;\s]? ''', re.X) 

Cuando ejecuto esto en python reg ex. probador, funciona maravillosamente

Data de muestra:

  

Dog

Cat

Fancy

Tall cup of lemons

Dog thing

Ahora, en la REDemo, funciona de maravilla.

Sin embargo, cuando lo puse en mi código de Python, solo se imprime

Aquí está mi código de Python, no estoy seguro si estoy haciendo algo mal o si algo se pierde en la traducción. Aprecio tu ayuda.

 stories=[] response = urllib2.urlopen('http://apricotclub.org/duh.html') html = response.read().lower() p = re.compile('\\s?()?\\s?[A-Za-z0-9.,:\'\"=/?;\\s]*\\s?[A-Za-z0-9.,:\'\"=/?;\\s]?') stories=re.findall(p, html) for i in stories: if len(i) >= 5: print i 

También debo tener en cuenta, que cuando saco el ()? a partir de la expresión regular funciona bien para líneas sin enlace .

Esta pregunta se ha formulado de varias formas en los últimos días, así que voy a decir esto muy claramente.

P: ¿Cómo puedo analizar HTML con expresiones regulares?

A: Por favor, no.

Utilice BeautifulSoup , html5lib o lxml.html . Por favor.

Analizar cosas con expresiones regulares funciona para lenguajes regulares. HTML no es un lenguaje regular, y lo que se encuentra en las páginas web en estos días es una mierda absoluta. BeautifulSoup se ocupa de las tags HTML de sopa con heurísticas similares a las de un navegador, por lo que obtiene un HTML analizado que se parece a lo que mostraría un navegador.

El inconveniente es que no es muy rápido. Hay lxml para analizar html bien formado, pero realmente debería usar BeautifulSoup si no está 100% seguro de que su entrada siempre estará bien formada.

Debido a las llaves alrededor de la etiqueta de anclaje, esa parte se interpreta como un grupo de captura. Esto hace que solo se devuelva el grupo de captura y no coincida toda la expresión regular.

Ponga la expresión regular completa entre llaves y verá que las coincidencias correctas se muestran como el primer elemento en las tuplas devueltas.

Pero de hecho, deberías usar un analizador real.

Basándonos en las respuestas hasta el momento:

Es mejor usar un motor de análisis. Puede cubrir una gran cantidad de casos y de una manera elegante. He probado BeautifulSoup y me gusta mucho. También es fácil de usar, con un gran tutorial.

Si a veces se siente como disparar moscas con un cañón, puedes usar una expresión regular para un análisis rápido. Si eso es lo que necesita aquí es el código modificado que capturará todos los encabezados (incluso aquellos sobre líneas múltiples):

 p = re.compile(r'<(h[0-9])>(.+?)', re.IGNORECASE | re.DOTALL) stories = re.findall(p, html) for i in stories: print i 

He usado beautifulsoup para analizar su HTML deseado. Tengo el código HTML anterior en un archivo llamado foo.html y luego lo leí como un objeto de archivo.

 from BeautifulSoup import BeautifulSoup H_TAGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] def extract_data(): """Extract the data from all headers in a HTML page.""" f = open('foo.html', 'r+') html = f.read() soup = BeautifulSoup(html) headers = [soup.findAll(h) for h in H_TAGS if soup.findAll(h)] lst = [] for x in headers: for y in x: if y.string: lst.append(y.string) else: lst.append(y.contents[0].string) return lst 

La función anterior devuelve:

 >>> [u'Dog ', u'Tall cup of lemons', u'Dog thing', u'Cat ', u'Fancy '] 

Puede agregar cualquier número de tags de encabezado en la lista h_tags. He asumido todos los encabezados. Si puedes resolver cosas fácilmente usando BeautifulSoup, entonces es mejor usarlo. 🙂

Como se ha mencionado, debe usar un analizador en lugar de una expresión regular.

Así es como puedes hacerlo con una expresión regular:

 import re html = '''  

Dog

Cat

Fancy

Tall cup of lemons

Dog thing

''' p = re.compile(r''' <(?P
h[0-9])> # store header tag for later use \s* # zero or more whitespace (.*?)">)? # optional link tag. store href portion \s* (?P.*?) # title \s* ()? # optional closing link tag \s* </(?P=header)> # must match opening header tag ''', re.IGNORECASE + re.VERBOSE) stories = p.finditer(html) for match in stories: print '%(title)s [%(href)s]' % match.groupdict()

Aquí hay un par de buenos recursos de expresiones regulares:

  • CÓMO de la expresión regular de Python
  • Regular-Expressions.info