Pregunta

Tengo un contenido HTML que se introduce por el usuario a través de un editor de texto enriquecido por lo que puede ser casi cualquier cosa (menos los que no supone que hay fuera del cuerpo de la etiqueta, no se preocupa por "cabeza" o tipo de documento, etc.). Un ejemplo de este contenido:

<h1>Header 1</h1>
<p>Some text here</p><p>Some more text here</p>
<div align=right><a href="x">A link here</a></div><hr />
<h1>Header 2</h1>
<p>Some text here</p><p>Some more text here</p>
<div align=right><a href="x">A link here</a></div><hr />

El truco es que necesito para extraer primeros 100 caracteres de sólo el texto (etiqueta HTML). También necesito para retener los saltos de línea y no romper ninguna palabra.

Así que la salida de lo anterior será algo como:

Header 1
Some text here

Some more text here

A link here

Header 2
Some text here

Some

Tiene 98 caracteres y saltos de línea se conservan. Lo que puedo lograr hasta ahora es despojar a la todas las etiquetas HTML usando expresiones regulares:

Regex.Replace(htmlStr, "<[^>]*>", "")

A continuación, recortar la longitud usando Regex, así como con:

Regex.Match(textStr, @"^.{1,100}\b").Value

Mi problema es, cómo retener el salto de línea ?. Consigo una salida como:

Header 1
Some text hereSome more text here
A link here
Header 2
Some text hereSome more text

Note las frases que unen? Tal vez alguien me puede mostrar algunas otras maneras de resolver este problema. Gracias!

Información adicional : Mi propósito es generar sinopsis de texto plano de un montón de contenido HTML. Supongo que esto ayudará a aclarar el problema.

¿Fue útil?

Solución 4

Bueno, tengo que cerrar esto sin embargo no tener la solución ideal. Dado que las etiquetas HTML utilizadas en mi aplicación son los muy comunes (no hay mesas, etc) la lista con poco o nada de anidación, lo que hice es preformat los fragmentos de HTML antes de que ellos guardar después de la entrada del usuario.

  • Eliminar todos los saltos de línea
  • Añadir un prefijo salto de línea a todas las etiquetas de bloque (por ejemplo div, p, h, h1 / 2/3/4 etc)

Antes de extraer de ellos hacia fuera que se mostrará como texto sin formato, utilizar expresiones regulares para eliminar la etiqueta html y retener la ruptura del verso. Casi ninguna ciencia de cohetes, pero funciona para mí.

Otros consejos

Creo que cómo iba a resolver esto es mirarlo como si se tratara de un simple navegador. Crear una clase de etiqueta de base, que sea abstracta con tal vez una propiedad InnerHTML y una PrintElement método virtual.

A continuación, crear clases para cada etiqueta HTML que se preocupa y se hereda de la clase base. A juzgar por su ejemplo, las etiquetas que más importan son H1, P, A, y h. Poner en práctica el método PrintElement tal que devuelve una cadena que imprime el elemento adecuadamente en base a la InnerHTML (como la clase p PrintElement volvería '\ n [InnerHTML] \ n').

A continuación, construir un analizador que analizar a través de su HTML y determinar cuál es el objeto de crear y luego añadir los objetos a una cola (un árbol sería mejor, pero no parece que sea necesario para sus fines).

Por último, ir a través de la cola de una llamada al método PrintElement para cada elemento.

Puede ser más trabajo de lo que había planeado, pero es una solución mucho más robusto que el simple uso de expresiones regulares y en caso de que decidió cambiar de opinión en el futuro y quieren mostrar estilo sencillo que es sólo una cuestión de ir hacia atrás y modificar su métodos PrintElement.

Para obtener información, despojando html con una expresión regular es ... lleno de problemas sutiles. El HTML agilidad Paquete puede ser más robusto, pero sufre todavía de las palabras sangrado juntos:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(html);
string text = doc.DocumentNode.InnerText;

Una forma podría ser para despojar html en tres pasos:

Regex.Replace(htmlStr, "<[^/>]*>", "") // don't strip </.*>
Regex.Replace(htmlStr, "</p>", "\r\n") // all paragraph ends are replaced w/ new line
Regex.Replace(htmlStr, "<[^>]*>", "") // replace remaining </.*>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top