Pergunta

Eu tenho um conteúdo HTML que é digitado pelo usuário através de um editor richtext por isso pode ser quase qualquer coisa (menos aqueles que não deveria estar fora da tag do corpo, não se preocupa com "cabeça" ou doctype etc). Um exemplo deste conteúdo:

<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 />

O truque é, eu preciso extrair primeiros 100 caracteres do texto somente (tags HTML despojado). Eu também preciso manter as quebras de linha e não quebrar qualquer palavra.

Assim, a saída para o acima será algo como:

Header 1
Some text here

Some more text here

A link here

Header 2
Some text here

Some

Tem 98 caracteres e quebras de linha são mantidas. O que posso conseguir até agora é tirar as todas as tags HTML usando Regex:

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

Em seguida, corte o comprimento usando Regex bem com:

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

O meu problema é, como reter a quebra de linha ?. Eu recebo uma saída como:

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

Observe as frases participar? Talvez alguém pode me mostrar algumas outras maneiras de resolver este problema. Obrigado!

Informação adicional : Meu propósito é gerar sinopse texto simples a partir de um monte de conteúdo HTML. Acho que isso vai ajudar a esclarecer a este problema.

Foi útil?

Solução 4

Bem, eu preciso fechar este apesar de não ter a solução ideal. Desde as tags HTML usado em meu aplicativo são os muito comuns (sem tabelas, lista etc) com pouco ou nenhum assentamento, o que eu fiz é preformat os fragmentos de HTML antes de salvá-los após a entrada do usuário.

  • Remover todas as quebras de linha
  • Adicionar um prefixo linha de quebra para todas as etiquetas (por exemplo, bloco div, p, h, H1 / 2/3/4, etc)

Antes de eu extraí-los para fora para ser exibido como texto simples, o uso regex para remover a tag html e manter a linha-break. Dificilmente qualquer ciência de foguetes, mas funciona para mim.

Outras dicas

Eu acho que como eu iria resolver isso é olhar para ele como se fosse um simples navegador. Criar uma classe base Tag, torná-lo abstrata com talvez uma propriedade InnerHTML e uma PrintElement método virtual.

Em seguida, criar classes para cada tag HTML que você se preocupa e herdar de sua classe base. A julgar pelo seu exemplo, as tags que você mais gosta são h1, p, a, e h. Implementar o método PrintElement tal que devolve uma cadeia que imprime o elemento adequadamente baseado na InnerHTML (como a classe p PrintElement voltaria '\ n [InnerHTML] \ n').

Em seguida, construir um analisador que irá analisar através de seu HTML e determinar qual objeto para criar e, em seguida, adicionar esses objetos para uma fila (a árvore seria melhor, mas não parece que é necessário para seus fins).

Finalmente, vá até a sua fila de chamar o método PrintElement para cada elemento.

Pode ser mais trabalho do que você tinha planejado, mas é uma solução muito mais robusta do que simplesmente usando regex e se você decidiu mudar de idéia no futuro e quer mostrar simples styling é apenas uma questão de voltar e modificar o seu métodos PrintElement.

Para informações, tirando html com um regex é ... cheio de problemas sutis. A HTML agilidade pack pode ser mais robusto, mas ainda sofre com as palavras sangrando juntos:

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

Uma maneira poderia ser para tirar html em três etapas:

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top