Pregunta

¿Hay alguna manera de dividir una larga cadena de HTML después de N palabras? Obviamente, podría usar:

' '.join(foo.split(' ')[:n])

para obtener los primeros n palabras de una cadena de texto sin formato, pero que podría dividir en medio de una etiqueta HTML, y no producirá HTML válido porque no va a cerrar las etiquetas que se han abierto.

Necesito hacer esto en un sitio Zope / Plone - si hay algo como estándar en aquellos productos que pueden hacerlo, que sería lo ideal

.

Por ejemplo, decir que tengo el texto:

<p>This is some text with a 
  <a href="http://www.example.com/" title="Example link">
     bit of linked text in it
  </a>.
</p>

Y lo pido para dividir después de 5 palabras, debe devolver:

<p>This is some text with</p>

7 palabras:

<p>This is some text with a 
  <a href="http://www.example.com/" title="Example link">
     bit
  </a>
</p>
¿Fue útil?

Solución

Tome un vistazo a la truncate_html_words función en django.utils.text. Incluso si usted no está usando Django, el código no hace exactamente lo que quiere.

Otros consejos

He oído que sopa Hermosa es muy bueno en el análisis de HTML. Probablemente será capaz de ayudarle a obtener html correcta a cabo.

Me iba a mencionar la base HTMLParser que se construye en Python, ya que no estoy seguro de lo que el resultado final de su tratando de llegar a decir, que puede o no puede llegar allí, que va a trabajar con los controladores principalmente

Se puede utilizar una mezcla de expresiones regulares, BeautifulSoup o Tidy (prefiero BeautifulSoup). La idea es simple - pelar todas las etiquetas HTML en primer lugar. Encuentra la palabra de orden n (n = 7 aquí), encontrar el número de veces que la palabra de orden n aparece en la cadena hasta el n palabras -. Coz u está buscando sólo para la última aparición a ser utilizado para el truncamiento

Aquí es una pieza de código, aunque un poco desordenado, pero funciona

import re
from BeautifulSoup import BeautifulSoup
import tidy

def remove_html_tags(data):
    p = re.compile(r'<.*?>')
    return p.sub('', data)

input_string='<p>This is some text with a <a href="http://www.example.com/" '\
    'title="Example link">bit of linked text in it</a></p>'

s=remove_html_tags(input_string).split(' ')[:7]

###required to ensure that only the last occurrence of the nth word is                                                                                      
#  taken into account for truncating.                                                                                                                       
#  coz if the nth word could be 'a'/'and'/'is'....etc                                                                                                       
#  which may occur multiple times within n words                                                                                                            
temp=input_string
k=s.count(s[-1])
i=1
j=0
while i<=k:
    j+=temp.find(s[-1])
    temp=temp[j+len(s[-1]):]
    i+=1
####                                                                                                                                                        
output_string=input_string[:j+len(s[-1])]

print "\nBeautifulSoup\n", BeautifulSoup(output_string)
print "\nTidy\n", tidy.parseString(output_string)

La salida es lo que quiere u

BeautifulSoup
<p>This is some text with a <a href="http://www.example.com/" title="Example link">bit</a></p>

Tidy
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 6 November 2007), see www.w3.org">
<title></title>
</head>
<body>
<p>This is some text with a <a href="http://www.example.com/"
title="Example link">bit</a></p>
</body>
</html>

Espero que esto ayude

Editar Una mejor expresión regular

`p = re.compile(r'<[^<]*?>')`
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top