tutorial studio parse from java html parsing

studio - parse html javascript



Eliminar etiquetas HTML de una cadena (27)

Alternativamente, uno puede usar HtmlCleaner :

private CharSequence removeHtmlFrom(String html) { return new HtmlCleaner().clean(html).getText(); }

¿Hay una buena manera de eliminar HTML de una cadena Java? Un simple regex como

replaceAll("//<.*?>","")

funcionará, pero cosas como &amp; no se convertirá correctamente y se eliminará el no HTML entre los dos corchetes angulares (es decir, desaparecerá el .*? en la expresión regular).


Aquí hay otra forma de hacerlo:

public static String removeHTML(String input) { int i = 0; String[] str = input.split(""); String s = ""; boolean inTag = false; for (i = input.indexOf("<"); i < input.indexOf(">"); i++) { inTag = true; } if (!inTag) { for (i = 0; i < str.length; i++) { s = s + str[i]; } } return s; }


Aquí hay una actualización ligeramente más completa para tratar de manejar algunos formatos para los descansos y las listas. Utilicé la salida de Amaya como guía.

import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.util.Stack; import java.util.logging.Logger; import javax.swing.text.MutableAttributeSet; import javax.swing.text.html.HTML; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.parser.ParserDelegator; public class HTML2Text extends HTMLEditorKit.ParserCallback { private static final Logger log = Logger .getLogger(Logger.GLOBAL_LOGGER_NAME); private StringBuffer stringBuffer; private Stack<IndexType> indentStack; public static class IndexType { public String type; public int counter; // used for ordered lists public IndexType(String type) { this.type = type; counter = 0; } } public HTML2Text() { stringBuffer = new StringBuffer(); indentStack = new Stack<IndexType>(); } public static String convert(String html) { HTML2Text parser = new HTML2Text(); Reader in = new StringReader(html); try { // the HTML to convert parser.parse(in); } catch (Exception e) { log.severe(e.getMessage()); } finally { try { in.close(); } catch (IOException ioe) { // this should never happen } } return parser.getText(); } public void parse(Reader in) throws IOException { ParserDelegator delegator = new ParserDelegator(); // the third parameter is TRUE to ignore charset directive delegator.parse(in, this, Boolean.TRUE); } public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) { log.info("StartTag:" + t.toString()); if (t.toString().equals("p")) { if (stringBuffer.length() > 0 && !stringBuffer.substring(stringBuffer.length() - 1) .equals("/n")) { newLine(); } newLine(); } else if (t.toString().equals("ol")) { indentStack.push(new IndexType("ol")); newLine(); } else if (t.toString().equals("ul")) { indentStack.push(new IndexType("ul")); newLine(); } else if (t.toString().equals("li")) { IndexType parent = indentStack.peek(); if (parent.type.equals("ol")) { String numberString = "" + (++parent.counter) + "."; stringBuffer.append(numberString); for (int i = 0; i < (4 - numberString.length()); i++) { stringBuffer.append(" "); } } else { stringBuffer.append("* "); } indentStack.push(new IndexType("li")); } else if (t.toString().equals("dl")) { newLine(); } else if (t.toString().equals("dt")) { newLine(); } else if (t.toString().equals("dd")) { indentStack.push(new IndexType("dd")); newLine(); } } private void newLine() { stringBuffer.append("/n"); for (int i = 0; i < indentStack.size(); i++) { stringBuffer.append(" "); } } public void handleEndTag(HTML.Tag t, int pos) { log.info("EndTag:" + t.toString()); if (t.toString().equals("p")) { newLine(); } else if (t.toString().equals("ol")) { indentStack.pop(); ; newLine(); } else if (t.toString().equals("ul")) { indentStack.pop(); ; newLine(); } else if (t.toString().equals("li")) { indentStack.pop(); ; newLine(); } else if (t.toString().equals("dd")) { indentStack.pop(); ; } } public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) { log.info("SimpleTag:" + t.toString()); if (t.toString().equals("br")) { newLine(); } } public void handleText(char[] text, int pos) { log.info("Text:" + new String(text)); stringBuffer.append(text); } public String getText() { return stringBuffer.toString(); } public static void main(String args[]) { String html = "<html><body><p>paragraph at start</p>hello<br />What is happening?<p>this is a<br />mutiline paragraph</p><ol> <li>This</li> <li>is</li> <li>an</li> <li>ordered</li> <li>list <p>with</p> <ul> <li>another</li> <li>list <dl> <dt>This</dt> <dt>is</dt> <dd>sdasd</dd> <dd>sdasda</dd> <dd>asda <p>aasdas</p> </dd> <dd>sdada</dd> <dt>fsdfsdfsd</dt> </dl> <dl> <dt>vbcvcvbcvb</dt> <dt>cvbcvbc</dt> <dd>vbcbcvbcvb</dd> <dt>cvbcv</dt> <dt></dt> </dl> <dl> <dt></dt> </dl></li> <li>cool</li> </ul> <p>stuff</p> </li> <li>cool</li></ol><p></p></body></html>"; System.out.println(convert(html)); } }


Aquí hay una variante más de cómo reemplazar todos (Etiquetas HTML | Entidades HTML | Espacio vacío en el contenido HTML)

content.replaceAll("(<.*?>)|(&.*?;)|([ ]{2,})", ""); donde el contenido es una cadena.


Creo que la forma más sencilla de filtrar las etiquetas html es:

private static final Pattern REMOVE_TAGS = Pattern.compile("<.+?>"); public static String removeTags(String string) { if (string == null || string.length() == 0) { return string; } Matcher m = REMOVE_TAGS.matcher(string); return m.replaceAll(""); }


Eliminar las etiquetas HTML de la cadena. En algún lugar tenemos que analizar algunas cadenas recibidas por algunas respuestas como Httpresponse del servidor.

Así que tenemos que analizarlo.

Aquí voy a mostrar cómo quitar las etiquetas html de la cadena.

// sample text with tags string str = "<html><head>sdfkashf sdf</head><body>sdfasdf</body></html>"; // regex which match tags System.Text.RegularExpressions.Regex rx = new System.Text.RegularExpressions.Regex("<[^>]*>"); // replace all matches with empty strin str = rx.Replace(str, ""); //now str contains string without html tags


En Android, prueba esto:

String result = Html.fromHtml(html).toString();


Es posible que desee reemplazar las etiquetas <br/> y </p> con nuevas líneas antes de eliminar el HTML para evitar que se convierta en un desastre ilegible como sugiere Tim.

La única forma en que puedo pensar en eliminar las etiquetas HTML, pero dejar el no HTML entre paréntesis angulares, se verifica en una lista de etiquetas HTML . Algo a lo largo de estas líneas ...

replaceAll("//<[/s]*tag[^>]*>","")

Luego, decodificar HTML caracteres especiales como &amp; . El resultado no debe considerarse saneado.


Escapar de HTML es muy difícil de hacer bien. Definitivamente, sugeriría usar un código de biblioteca para hacer esto, ya que es mucho más sutil de lo que piensas. Echa un vistazo a StringEscapeUtils de Apache para una biblioteca bastante buena para manejar esto en Java.


Esto debería funcionar -

utilizar esta

text.replaceAll(''<.*?>'' , " ") -> This will replace all the html tags with a space.

y esto

text.replaceAll(''&.*?;'' , "")-> this will replace all the tags which starts with "&" and ends with ";" like &nbsp;, &amp;, &gt; etc.


La respuesta aceptada de hacer simplemente Jsoup.parse(html).text() tiene 2 problemas potenciales (con JSoup 1.7.3):

  • Elimina saltos de línea del texto.
  • Convierte texto &lt;script&gt; en <script>

Si usa esto para protegerse contra XSS, esto es un poco molesto. Aquí está mi mejor oportunidad para una solución mejorada, utilizando tanto JSoup como Apache StringEscapeUtils:

// breaks multi-level of escaping, preventing &amp;lt;script&amp;gt; to be rendered as <script> String replace = input.replace("&amp;", ""); // decode any encoded html, preventing &lt;script&gt; to be rendered as <script> String html = StringEscapeUtils.unescapeHtml(replace); // remove all html tags, but maintain line breaks String clean = Jsoup.clean(html, "", Whitelist.none(), new Document.OutputSettings().prettyPrint(false)); // decode html again to convert character entities back into text return StringEscapeUtils.unescapeHtml(clean);

Tenga en cuenta que el último paso es porque necesito usar la salida como texto sin formato. Si solo necesita una salida HTML, debería poder eliminarlo.

Y aquí hay un montón de casos de prueba (entrada a salida):

{"regular string", "regular string"}, {"<a href=/"link/">A link</a>", "A link"}, {"<script src=/"http://evil.url.com/"/>", ""}, {"&lt;script&gt;", ""}, {"&amp;lt;script&amp;gt;", "lt;scriptgt;"}, // best effort {"/" '' > < /n // é å à ü and & preserved", "/" '' > < /n // é å à ü and & preserved"}

Si encuentra una manera de mejorarlo, hágamelo saber.


La respuesta aceptada no me funcionó para el caso de prueba que indiqué: el resultado de "a <b o b> c" es "ab or b> c".

Por lo tanto, utilicé TagSoup en su lugar. Aquí hay una foto que funcionó para mi caso de prueba (y un par de otros):

import java.io.IOException; import java.io.StringReader; import java.util.logging.Logger; import org.ccil.cowan.tagsoup.Parser; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; /** * Take HTML and give back the text part while dropping the HTML tags. * * There is some risk that using TagSoup means we''ll permute non-HTML text. * However, it seems to work the best so far in test cases. * * @author dan * @see <a href="http://home.ccil.org/~cowan/XML/tagsoup/">TagSoup</a> */ public class Html2Text2 implements ContentHandler { private StringBuffer sb; public Html2Text2() { } public void parse(String str) throws IOException, SAXException { XMLReader reader = new Parser(); reader.setContentHandler(this); sb = new StringBuffer(); reader.parse(new InputSource(new StringReader(str))); } public String getText() { return sb.toString(); } @Override public void characters(char[] ch, int start, int length) throws SAXException { for (int idx = 0; idx < length; idx++) { sb.append(ch[idx+start]); } } @Override public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { sb.append(ch); } // The methods below do not contribute to the text @Override public void endDocument() throws SAXException { } @Override public void endElement(String uri, String localName, String qName) throws SAXException { } @Override public void endPrefixMapping(String prefix) throws SAXException { } @Override public void processingInstruction(String target, String data) throws SAXException { } @Override public void setDocumentLocator(Locator locator) { } @Override public void skippedEntity(String name) throws SAXException { } @Override public void startDocument() throws SAXException { } @Override public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { } @Override public void startPrefixMapping(String prefix, String uri) throws SAXException { } }


Mis 5 centavos:

String[] temp = yourString.split("&amp;"); String tmp = ""; if (temp.length > 1) { for (int i = 0; i < temp.length; i++) { tmp += temp[i] + "&"; } yourString = tmp.substring(0, tmp.length() - 1); }


Otra forma es usar javax.swing.text.html.HTMLEditorKit para extraer el texto.

import java.io.*; import javax.swing.text.html.*; import javax.swing.text.html.parser.*; public class Html2Text extends HTMLEditorKit.ParserCallback { StringBuffer s; public Html2Text() { } public void parse(Reader in) throws IOException { s = new StringBuffer(); ParserDelegator delegator = new ParserDelegator(); // the third parameter is TRUE to ignore charset directive delegator.parse(in, this, Boolean.TRUE); } public void handleText(char[] text, int pos) { s.append(text); } public String getText() { return s.toString(); } public static void main(String[] args) { try { // the HTML to convert FileReader in = new FileReader("java-new.html"); Html2Text parser = new Html2Text(); parser.parse(in); in.close(); System.out.println(parser.getText()); } catch (Exception e) { e.printStackTrace(); } } }

ref: elimina las etiquetas HTML de un archivo para extraer solo el TEXTO


Para obtener texto html simple formateado puedes hacer eso:

String BR_ESCAPED = "&lt;br/&gt;"; Element el=Jsoup.parse(html).select("body"); el.select("br").append(BR_ESCAPED); el.select("p").append(BR_ESCAPED+BR_ESCAPED); el.select("h1").append(BR_ESCAPED+BR_ESCAPED); el.select("h2").append(BR_ESCAPED+BR_ESCAPED); el.select("h3").append(BR_ESCAPED+BR_ESCAPED); el.select("h4").append(BR_ESCAPED+BR_ESCAPED); el.select("h5").append(BR_ESCAPED+BR_ESCAPED); String nodeValue=el.text(); nodeValue=nodeValue.replaceAll(BR_ESCAPED, "<br/>"); nodeValue=nodeValue.replaceAll("(//s*<br[^>]*>){3,}", "<br/><br/>");

Para obtener un formato de texto simple formateado <br/> por / ny cambie la última línea mediante:

nodeValue=nodeValue.replaceAll("(//s*/n){3,}", "<br/><br/>");


Parece que quieres pasar de HTML a texto plano.
Si ese es el caso, visite www.htmlparser.org. Aquí hay un ejemplo que elimina todas las etiquetas del archivo html encontrado en una URL.
Hace uso de org.htmlparser.beans.StringBean .

static public String getUrlContentsAsText(String url) { String content = ""; StringBean stringBean = new StringBean(); stringBean.setURL(url); content = stringBean.getStrings(); return content; }


Sé que esto es antiguo, pero estaba trabajando en un proyecto que me obligó a filtrar HTML y esto funcionó bien:

noHTMLString.replaceAll("//&.*?//;", "");

en lugar de esto:

html = html.replaceAll("&nbsp;",""); html = html.replaceAll("&amp;"."");


Si el usuario ingresa <b>hey!</b> , ¿desea mostrar <b>hey!</b> o hey! ? Si es el primero, escapa los compases y codifica html (y, opcionalmente, comillas) y está bien. Una modificación a su código para implementar la segunda opción sería:

replaceAll("//<[^>]*>","")

pero se encontrará con problemas si el usuario ingresa algo mal formado, como <bhey!</b> .

También puede consultar JTidy que analizará la entrada html "sucia", y le dará una forma de eliminar las etiquetas, manteniendo el texto.

El problema al tratar de eliminar HTML es que los navegadores tienen analizadores muy indulgentes, más indulgentes que cualquier biblioteca que pueda encontrar, así que incluso si hace todo lo posible por eliminar todas las etiquetas (utilizando el método de reemplazo anterior, una biblioteca DOM o JTidy) , aún deberá asegurarse de codificar los caracteres especiales de HTML restantes para mantener su salida segura.


Si estás escribiendo para Android puedes hacer esto ...

android.text.Html.fromHtml(instruction).toString()


También es muy sencillo utilizar Jericho , y puede conservar parte del formato (por ejemplo, saltos de línea y enlaces).

Source htmlSource = new Source(htmlText); Segment htmlSeg = new Segment(htmlSource, 0, htmlSource.length()); Renderer htmlRend = new Renderer(htmlSeg); System.out.println(htmlRend.toString());


También se podría usar Apache Tika para este propósito. Por defecto, conserva los espacios en blanco del html eliminado, lo que puede ser deseado en ciertas situaciones:

InputStream htmlInputStream = .. HtmlParser htmlParser = new HtmlParser(); HtmlContentHandler htmlContentHandler = new HtmlContentHandler(); htmlParser.parse(htmlInputStream, htmlContentHandler, new Metadata()) System.out.println(htmlContentHandler.getBodyText().trim())


Una forma de retener información de nueva línea con JSoup es preceder a todas las nuevas etiquetas de línea con alguna cadena ficticia, ejecutar JSoup y reemplazar la cadena ficticia con "/ n".

String html = "<p>Line one</p><p>Line two</p>Line three<br/>etc."; String NEW_LINE_MARK = "NEWLINESTART1234567890NEWLINEEND"; for (String tag: new String[]{"</p>","<br/>","</h1>","</h2>","</h3>","</h4>","</h5>","</h6>","</li>"}) { html = html.replace(tag, NEW_LINE_MARK+tag); } String text = Jsoup.parse(html).text(); text = text.replace(NEW_LINE_MARK + " ", "/n/n"); text = text.replace(NEW_LINE_MARK, "/n/n");


Una forma más puede ser usar la clase com.google.gdata.util.common.html.HtmlToText como

MyWriter.toConsole(HtmlToText.htmlToPlainText(htmlResponse));

Sin embargo, este no es un código a prueba de balas y cuando lo ejecuto en entradas de wikipedia también obtengo información de estilo Sin embargo, creo que para trabajos pequeños / simples esto sería efectivo.


Utilice Html.fromHtml

Las etiquetas HTML son

<a href=”…”> <b>, <big>, <blockquote>, <br>, <cite>, <dfn> <div align=”…”>, <em>, <font size=”…” color=”…” face=”…”> <h1>, <h2>, <h3>, <h4>, <h5>, <h6> <i>, <p>, <small> <strike>, <strong>, <sub>, <sup>, <tt>, <u>

Según las Documentaciones oficiales de Android, todas las etiquetas en el HTML se mostrarán como una Cadena de reemplazo genérica por la cual su programa puede pasar y reemplazarse por cadenas reales.

Html.formHtml método Html.formHtml toma un Html.TagHandler y un Html.ImageGetter como argumentos, así como el texto a analizar.

Ejemplo

String Str_Html=" <p>This is about me text that the user can put into their profile</p> ";

Entonces

Your_TextView_Obj.setText(Html.fromHtml(Str_Html).toString());

Salida

Se trata del texto que el usuario puede poner en su perfil.


Utilice un analizador de HTML en lugar de expresiones regulares. Esto es muy simple con Jsoup .

public static String html2text(String html) { return Jsoup.parse(html).text(); }

Jsoup también supports eliminación de etiquetas HTML en una lista blanca personalizable, lo cual es muy útil si solo desea permitir, por ejemplo, <b> , <i> y <u> .

Ver también:


ej: classeString.replaceAll ("/ <(/? [^ />] +) />", "/") .replaceAll ("/ s +", "") .trim ()


simplemente puede hacer un método con múltiples replaceAll () como

String RemoveTag(String html){ html = html.replaceAll("//<.*?>","") html = html.replaceAll("&nbsp;",""); html = html.replaceAll("&amp;".""); ---------- ---------- return html; }

Use este enlace para los reemplazos más comunes que necesita: http://tunes.org/wiki/html_20special_20characters_20and_20symbols.html

Es simple, pero efectivo. Primero utilizo este método para eliminar la basura, pero no la primera línea, es decir, reemplazar todo ("/ <. *?>", ""), Y luego uso palabras clave específicas para buscar índices y luego uso .substring (inicio, final) ) Método para quitar cosas innecesarias. Como esto es más robusto y puede señalar exactamente lo que necesita en toda la página html.