parse - text to string javascript
Eliminar HTML de texto JavaScript (30)
Conversión de HTML para mensajes de texto sin formato manteniendo los hipervínculos (a href) intactos
La función anterior publicada por hypoxide funciona bien, pero buscaba algo que básicamente convirtiera el HTML creado en un editor de texto enriquecido de la Web (por ejemplo, FCKEditor) y borrase todo el HTML pero dejara todos los enlaces debido al hecho de que quería el HTML y la versión de texto sin formato para ayudar a crear las partes correctas en un correo electrónico de STMP (tanto HTML como texto sin formato).
Después de mucho tiempo de buscar en Google, a mí mismo ya mis colegas se les ocurrió esto usando el motor de expresiones regulares en Javascript:
str=''this string has <i>html</i> code i want to <b>remove</b><br>Link Number 1 -><a href="http://www.bbc.co.uk">BBC</a> Link Number 1<br><p>Now back to normal text and stuff</p>
'';
str=str.replace(/<br>/gi, "/n");
str=str.replace(/<p.*>/gi, "/n");
str=str.replace(/<a.*href="(.*?)".*>(.*?)<//a>/gi, " $2 (Link->$1) ");
str=str.replace(/<(?:.|/s)*?>/g, "");
La variable str
comienza así:
this string has <i>html</i> code i want to <b>remove</b><br>Link Number 1 -><a href="http://www.bbc.co.uk">BBC</a> Link Number 1<br><p>Now back to normal text and stuff</p>
y luego, después de que el código se ha ejecutado, se ve así:
this string has html code i want to remove
Link Number 1 -> BBC (Link->http://www.bbc.co.uk) Link Number 1
Now back to normal text and stuff
Como puede ver, todo el HTML ha sido eliminado y el enlace ha sido perseverado con el texto del hipervínculo que sigue intacto. También he reemplazado las etiquetas <p>
y <br>
con /n
(nueva línea de caracteres) para que se retenga algún tipo de formato visual.
Para cambiar el formato del enlace (por ejemplo, BBC (Link->http://www.bbc.co.uk)
) simplemente edite los $2 (Link->$1)
, donde $1
es la URL href / URI y el $2
es la texto hipervinculado. Con los enlaces directamente en el cuerpo del texto sin formato, la mayoría de los clientes de correo SMTP los convierten para que el usuario pueda hacer clic en ellos.
Espero que encuentres esto útil.
¿Hay una manera fácil de tomar una cadena de html en JavaScript y eliminar el html?
Aquí hay una versión que aborda el problema de seguridad de @ MikeSamuel:
function strip(html)
{
try {
var doc = document.implementation.createDocument(''http://www.w3.org/1999/xhtml'', ''html'', null);
doc.documentElement.innerHTML = html;
return doc.documentElement.textContent||doc.documentElement.innerText;
} catch(e) {
return "";
}
}
Tenga en cuenta que devolverá una cadena vacía si el marcado HTML no es un XML válido (también conocido como, las etiquetas deben cerrarse y los atributos deben estar entre comillas). Esto no es ideal, pero evita el problema de tener el potencial de explotación de seguridad.
Si no es un requisito tener un marcado XML válido, puede intentar usar:
var doc = document.implementation.createHTMLDocument("");
Pero esa tampoco es una solución perfecta por otras razones.
Como una extensión del método jQuery, si su cadena puede no contener HTML (por ejemplo, si está intentando eliminar HTML de un campo de formulario)
jQuery(html).text();
devolverá una cadena vacía si no hay html
Utilizar:
jQuery(''<p>'' + html + ''</p>'').text();
en lugar.
Actualización: Como se ha señalado en los comentarios, en algunas circunstancias esta solución ejecutará javascript contenido en html
si el atacante puede influir en el valor de html
, use una solución diferente.
Con jQuery puedes simplemente recuperarlo usando
$(''#elementID'').text()
Creo que la forma más sencilla es usar expresiones regulares como alguien mencionado anteriormente. Aunque no hay razón para usar un montón de ellos. Tratar:
stringWithHTML = stringWithHTML.replace(/<//?[a-z][a-z0-9]*[^<>]*>/ig, "");
Después de probar todas las respuestas, la mayoría mencionó, si no todas, tenían casos de ventaja y no podían satisfacer mis necesidades por completo.
Comencé a explorar cómo lo hace php y encontré php.js lib que replica el método strip_tags aquí: http://phpjs.org/functions/strip_tags/
El código siguiente le permite retener algunas etiquetas html mientras elimina todos los demás
function strip_tags(input, allowed) {
allowed = (((allowed || '''') + '''')
.toLowerCase()
.match(/<[a-z][a-z0-9]*>/g) || [])
.join(''''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
var tags = /<//?([a-z][a-z0-9]*)/b[^>]*>/gi,
commentsAndPhpTags = /<!--[/s/S]*?-->|</?(?:php)?[/s/S]*?/?>/gi;
return input.replace(commentsAndPhpTags, '''')
.replace(tags, function($0, $1) {
return allowed.indexOf(''<'' + $1.toLowerCase() + ''>'') > -1 ? $0 : '''';
});
}
Esto debería funcionar en cualquier entorno de Javascript (NodeJS incluido). text.replace(/<[^>]+>/g, '''');
Hice algunas modificaciones al script original de Jibberboy2000. Espero que sea útil para alguien.
str = ''**ANY HTML CONTENT HERE**'';
str=str.replace(/</s*br//*>/gi, "/n");
str=str.replace(/</s*a.*href="(.*?)".*>(.*?)<//a>/gi, " $2 (Link->$1) ");
str=str.replace(/</s*//*.+?>/ig, "/n");
str=str.replace(/ {2,}/gi, " ");
str=str.replace(//n+/s*/gi, "/n/n");
JQuery simple de 2 líneas para quitar el html.
var content = "<p>checking the html source </p><p>
</p><p>with </p><p>all</p><p>the html </p><p>content</p>";
var text = $(content).text();//It gets you the plain text
console.log(text);//check the data in your console
cj("#text_area_id").val(text);//set your content to text area using text_area_id
La respuesta aceptada funciona bien principalmente, sin embargo, en IE, si la cadena html
es null
se obtiene el "null"
(en lugar de ''''). Fijo:
function strip(html)
{
if (html == null) return "";
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
Manera más simple:
jQuery(html).text();
Que recupera todo el texto de una cadena de html.
Me gustaría compartir una versión editada de la respuesta aprobada de Shog9 .
Como Mike Samuel señaló con un comentario, esa función puede ejecutar códigos javascript en línea.
Pero Shog9 tiene razón cuando dice "deja que el navegador lo haga por ti ..."
así que ... aquí mi versión editada, usando DOMParser :
function strip(html){
var doc = new DOMParser().parseFromString(html, ''text/html'');
return doc.body.textContent || "";
}
Aquí el código para probar el javascript en línea:
strip("<img onerror=''alert(/"could run arbitrary JS here/")'' src=bogus>")
Además, no solicita recursos en el análisis (como imágenes)
strip("Just text <img src=''https://assets.rbl.ms/4155638/980x.jpg''>")
Mucha gente ya ha respondido a esto, pero pensé que podría ser útil compartir la función que escribí que elimina las etiquetas HTML de una cadena, pero le permite incluir una serie de etiquetas que no desea eliminar. Es bastante corto y ha estado trabajando muy bien para mí.
function removeTags(string, array){
return array ? string.split("<").filter(function(val){ return f(array, val); }).map(function(val){ return f(array, val); }).join("") : string.split("<").map(function(d){ return d.split(">").pop(); }).join("");
function f(array, value){
return array.map(function(d){ return value.includes(d + ">"); }).indexOf(true) != -1 ? "<" + value : value.split(">")[1];
}
}
var x = "<span><i>Hello</i> <b>world</b>!</span>";
console.log(removeTags(x)); // Hello world!
console.log(removeTags(x, ["span", "i"])); // <span><i>Hello</i> world!</span>
Otra solución, ciertamente menos elegante que las de nickf o shog9, sería recorrer el DOM de forma recursiva a partir de la etiqueta <body> y agregar cada nodo de texto.
var bodyContent = document.getElementsByTagName(''body'')[0];
var result = appendTextNodes(bodyContent);
function appendTextNodes(element) {
var text = '''';
// Loop through the childNodes of the passed in element
for (var i = 0, len = element.childNodes.length; i < len; i++) {
// Get a reference to the current child
var node = element.childNodes[i];
// Append the node''s value if it''s a text node
if (node.nodeType == 3) {
text += node.nodeValue;
}
// Recurse through the node''s children, if there are any
if (node.childNodes.length > 0) {
appendTextNodes(node);
}
}
// Return the final result
return text;
}
Para los personajes de escape, esto también funcionará utilizando la coincidencia de patrones:
myString.replace(/((<)|(<)(?:.|/n)*?(>)|(>))/gm, '''');
Puede eliminar de forma segura las etiquetas html utilizando el atributo iframe sandbox .
La idea aquí es que, en lugar de intentar regexar nuestra cadena, aprovechamos el analizador nativo del navegador inyectando el texto en un elemento DOM y luego consultando la propiedad textContent
/ innerText
de ese elemento.
El elemento más adecuado para inyectar nuestro texto es un iframe de espacio aislado, de esa manera podemos evitar cualquier ejecución de código arbitrario (también conocido como XSS ).
La desventaja de este enfoque es que solo funciona en los navegadores.
Esto es lo que se me ocurrió (no probado en batalla):
const stripHtmlTags = (() => {
const sandbox = document.createElement("iframe");
sandbox.sandbox = "allow-same-origin"; // <--- This is the key
sandbox.style.setProperty("display", "none", "important");
// Inject the sanbox in the current document
document.body.appendChild(sandbox);
// Get the sandbox''s context
const sanboxContext = sandbox.contentWindow.document;
return (untrustedString) => {
if (typeof untrustedString !== "string") return "";
// Write the untrusted string in the iframe''s body
sanboxContext.open();
sanboxContext.write(untrustedString);
sanboxContext.close();
// Get the string without html
return sanboxContext.body.textContent || sanboxContext.body.innerText || "";
};
})();
Uso ( demo ):
console.log(stripHtmlTags(`<img onerror=''alert("could run arbitrary JS here")'' src=''bogus''>XSS injection :)`));
console.log(stripHtmlTags(`<script>alert("awdawd");</` + `script>Script tag injection :)`));
console.log(stripHtmlTags(`<strong>I am bold text</strong>`));
console.log(stripHtmlTags(`<html>I''m a HTML tag</html>`));
console.log(stripHtmlTags(`<body>I''m a body tag</body>`));
console.log(stripHtmlTags(`<head>I''m a head tag</head>`));
console.log(stripHtmlTags(null));
Si desea mantener los enlaces y la estructura del contenido (h1, h2, etc.), debería revisar TextVersionJS . Puede usarlo con cualquier HTML, aunque se creó para convertir un correo electrónico HTML a texto sin formato.
El uso es muy sencillo. Por ejemplo en node.js:
var createTextVersion = require("textversionjs");
var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
var textVersion = createTextVersion(yourHtml);
O en el navegador con js puro:
<script src="textversion.js"></script>
<script>
var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
var textVersion = createTextVersion(yourHtml);
</script>
También funciona con require.js:
define(["textversionjs"], function(createTextVersion) {
var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
var textVersion = createTextVersion(yourHtml);
});
Si está ejecutando en un navegador, la forma más sencilla es dejar que el navegador lo haga por usted ...
function strip(html)
{
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
Nota: como la gente ha notado en los comentarios, esto es mejor evitarlo si no controla la fuente del HTML (por ejemplo, no ejecute esto en nada que pueda provenir de la entrada del usuario). Para esos escenarios, aún puede dejar que el navegador haga el trabajo por usted; vea la respuesta de Saba sobre el uso del DOMParser, que ahora está ampliamente disponible .
Solo necesitaba quitar las etiquetas <a>
y reemplazarlas con el texto del enlace.
Esto parece funcionar muy bien.
htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '''');
htmlContent= htmlContent.replace(/<//a>/g, '''');
También es posible usar el fantástico analizador HTML HTML puro htmlparser2 . Aquí hay una demostración de trabajo:
var htmlparser = require(''htmlparser2'');
var body = ''<p><div>This is </div>a <span>simple </span> <img src="test"></img>example.</p>'';
var result = [];
var parser = new htmlparser.Parser({
ontext: function(text){
result.push(text);
}
}, {decodeEntities: true});
parser.write(body);
parser.end();
result.join('''');
La salida será This is a simple example.
Véalo en acción aquí: https://tonicdev.com/jfahrenkrug/extract-text-from-html
Esto funciona tanto en el nodo como en el navegador si empaqueta su aplicación web utilizando una herramienta como webpack.
Una mejora a la respuesta aceptada.
function strip(html)
{
var tmp = document.implementation.createHTMLDocument("New").body;
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
De esta manera, algo como esto no hará daño:
strip("<img onerror=''alert(/"could run arbitrary JS here/")'' src=bogus>")
Firefox, Chromium y Explorer 9+ son seguros. Opera Presto sigue siendo vulnerable. Además, las imágenes mencionadas en las cadenas no se descargan en Chromium y Firefox guardando solicitudes http.
Utilizando Jquery:
function stripTags() {
return $(''<p></p>'').html(textToEscape).text()
}
Yo mismo he creado una expresión regular de trabajo:
str=str.replace(/(</?[a-z]*(/s[^>]*)?/?(>|$)|<!/[[a-z]*/[|/]/]>|<!DOCTYPE[^>]*?(>|$)|<!--[/s/S]*?(-->|$)|<[a-z?!//]([a-z0-9_:.])*(/s[^>]*)?(>|$))/gi, '''');
input
elemento de input
admite solo una línea de texto :
El estado del texto representa un control de edición de texto sin formato de una línea para el valor del elemento.
function stripHtml(str) {
var tmp = document.createElement(''input'');
tmp.value = str;
return tmp.value;
}
Actualización: esto funciona como se esperaba
function stripHtml(str) {
// Remove some tags
str = str.replace(/<[^>]+>/gim, '''');
// Remove BB code
str = str.replace(//[(/w+)[^/]]*](.*?)/[///1]/g, ''$2 '');
// Remove html and line breaks
const div = document.createElement(''div'');
div.innerHTML = str;
const input = document.createElement(''input'');
input.value = div.textContent || div.innerText || '''';
return input.value;
}
Modifiqué la respuesta de Jibberboy2000 para incluir varios formatos de etiquetas <BR />
todo lo que estaba dentro de las etiquetas <SCRIPT>
y <STYLE>
, formateé el HTML resultante eliminando múltiples saltos de línea y espacios y convertí algo de código codificado en HTML a normal. Después de algunas pruebas, parece que puede convertir la mayoría de las páginas web completas en texto simple donde se conservan el título y el contenido de la página.
En el ejemplo simple,
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<!--comment-->
<head>
<title>This is my title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style>
body {margin-top: 15px;}
a { color: #D80C1F; font-weight:bold; text-decoration:none; }
</style>
</head>
<body>
<center>
This string has <i>html</i> code i want to <b>remove</b><br>
In this line <a href="http://www.bbc.co.uk">BBC</a> with link is mentioned.<br/>Now back to "normal text" and stuff using <html encoding>
</center>
</body>
</html>
se convierte en
Este es mi titulo
Esta cadena tiene código html que quiero eliminar
En esta línea se menciona la BBC ( http://www.bbc.co.uk ) con enlace.
Ahora volvamos al "texto normal" y esas cosas usando
La función de JavaScript y la página de prueba tienen este aspecto:
function convertHtmlToText() {
var inputText = document.getElementById("input").value;
var returnText = "" + inputText;
//-- remove BR tags and replace them with line break
returnText=returnText.replace(/<br>/gi, "/n");
returnText=returnText.replace(/<br/s//>/gi, "/n");
returnText=returnText.replace(/<br//>/gi, "/n");
//-- remove P and A tags but preserve what''s inside of them
returnText=returnText.replace(/<p.*>/gi, "/n");
returnText=returnText.replace(/<a.*href="(.*?)".*>(.*?)<//a>/gi, " $2 ($1)");
//-- remove all inside SCRIPT and STYLE tags
returnText=returnText.replace(/<script.*>[/w/W]{1,}(.*?)[/w/W]{1,}<//script>/gi, "");
returnText=returnText.replace(/<style.*>[/w/W]{1,}(.*?)[/w/W]{1,}<//style>/gi, "");
//-- remove all else
returnText=returnText.replace(/<(?:.|/s)*?>/g, "");
//-- get rid of more than 2 multiple line breaks:
returnText=returnText.replace(/(?:(?:/r/n|/r|/n)/s*){2,}/gim, "/n/n");
//-- get rid of more than 2 spaces:
returnText = returnText.replace(/ +(?= )/g,'''');
//-- get rid of html-encoded characters:
returnText=returnText.replace(/ /gi," ");
returnText=returnText.replace(/&/gi,"&");
returnText=returnText.replace(/"/gi,''"'');
returnText=returnText.replace(/</gi,''<'');
returnText=returnText.replace(/>/gi,''>'');
//-- return
document.getElementById("output").value = returnText;
}
Fue utilizado con este HTML:
<textarea id="input" style="width: 400px; height: 300px;"></textarea><br />
<button onclick="convertHtmlToText()">CONVERT</button><br />
<textarea id="output" style="width: 400px; height: 300px;"></textarea><br />
(function($){
$.html2text = function(html) {
if($(''#scratch_pad'').length === 0) {
$(''<div id="lh_scratch"></div>'').appendTo(''body'');
}
return $(''#scratch_pad'').html(html).text();
};
})(jQuery);
Defina esto como un complemento de jQuery y utilícelo de la siguiente manera:
$.html2text(htmlContent);
function stripHTML(my_string){
var charArr = my_string.split(''''),
resultArr = [],
htmlZone = 0,
quoteZone = 0;
for( x=0; x < charArr.length; x++ ){
switch( charArr[x] + htmlZone + quoteZone ){
case "<00" : htmlZone = 1;break;
case ">10" : htmlZone = 0;resultArr.push('' '');break;
case ''"10'' : quoteZone = 1;break;
case "''10" : quoteZone = 2;break;
case ''"11'' :
case "''12" : quoteZone = 0;break;
default : if(!htmlZone){ resultArr.push(charArr[x]); }
}
}
return resultArr.join('''');
}
Cuentas para> atributos internos y <img onerror="javascript">
en elementos de dom creados recientemente.
uso:
clean_string = stripHTML("string with <html> in it")
manifestación:
https://jsfiddle.net/gaby_de_wilde/pqayphzd/
Demostración de la mejor respuesta haciendo las cosas terribles.
myString.replace(/<(?:.|/n)*?>/gm, '''');
var text = html.replace(/<//?("[^"]*"|''[^'']*''|[^>])*(>|$)/g, "");
Esta es una versión de expresiones regulares, que es más resistente al HTML mal formado, como:
Etiquetas sin cerrar
Some text <img
"<", ">" dentro de los atributos de la etiqueta
Some text <img alt="x > y">
Nuevas lineas
Some <a href="http://google.com">
El código
var html = ''<br>This <img alt="a>b" /r/n src="a_b.gif" />is > /nmy<>< > <a>"text"</a''
var text = html.replace(/<//?("[^"]*"|''[^'']*''|[^>])*(>|$)/g, "");