Supprimer HTML du texte JavaScript
Est-il un moyen facile de prendre une chaîne de html en JavaScript et dépouiller le html?
30 réponses
si vous utilisez un navigateur, alors la façon la plus simple est juste de laisser le navigateur le faire pour vous...
function strip(html)
{
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
Note: Comme les gens l'ont noté dans les commentaires, ceci est mieux évité si vous ne contrôlez pas la source du HTML (par exemple, ne l'exécutez pas sur quoi que ce soit qui aurait pu venir de l'entrée de l'utilisateur). Pour ces scénarios, vous pouvez encore laisser le navigateur faire le travail pour vous - voir la réponse de Saba sur en utilisant le DOMParser maintenant largement disponible .
la manière la plus simple:
jQuery(html).text();
qui récupère tout le texte d'une chaîne de caractères html.
comme extension de la méthode jQuery, si votre chaîne ne contient pas HTML (par exemple si vous essayez de supprimer HTML d'un champ de formulaire)
jQuery(html).text();
retournera une chaîne vide s'il n'y a pas de html
Utiliser:
jQuery('<p>' + html + '</p>').text();
à la place.
mise à Jour:
Comme cela a été souligné dans les commentaires, dans certains circonstances Cette solution exécutera javascript contenu dans html
si la valeur de html
pourrait être influencée par un attaquant, utiliser une solution différente.
je voudrais partager une version révisée de la Shog9 approuvé réponse .
Comme Mike Samuel , a souligné avec un commentaire, cette fonction peut exécuter du javascript en ligne codes.
Mais Shog9 est juste en disant " Laissez le navigateur le faire pour vous..."
so.. voici ma version modifiée, en utilisant DOMParser :
function strip(html){
var doc = new DOMParser().parseFromString(html, 'text/html');
return doc.body.textContent || "";
}
voici le code pour tester le javascript en ligne:
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
aussi, il ne demande pas de ressources sur parse (comme des images)
strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")
conversion HTML pour L'envoi de texte en clair conserver les hyperliens (a href) intacts
la fonction ci-dessus posté par hypoxide fonctionne très bien, mais j'étais après quelque chose qui convertirait essentiellement HTML créé dans un éditeur Web RichText (par exemple FCKEditor) et effacer tout HTML mais laisser tous les liens en raison du fait que je voulais à la fois le HTML et la version de texte en clair pour aider à créer les parties correctes à un email STMP (à la fois HTML et texte en clair).
après une longue période de recherche sur Google, mes collègues et moi-même avons trouvé ceci en utilisant le moteur regex 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, " (Link->) ");
str=str.replace(/<(?:.|\s)*?>/g, "");
la variable str
commence ainsi:
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>
et puis après que le code a fonctionné il ressemble à ceci: -
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
comme vous pouvez le voir le tout le HTML a été supprimé et le lien ont été persévérés avec le texte hypertexte est encore intact. Aussi, Je ont remplacé les étiquettes <p>
et <br>
par \n
(newline char) de sorte qu'une sorte de formatage visuel a été conservée.
pour changer le format du lien (par ex. BBC (Link->http://www.bbc.co.uk)
) il suffit de modifier le (Link->)
, où est L'URL href/URI et le
est le texte hypertexte. Avec les liens directement dans le corps du texte clair, la plupart des clients de messagerie SMTP convertissent ceux-ci afin que l'utilisateur ait la possibilité de cliquer sur eux.
J'espère que vous trouverez cela utile.
une amélioration à la réponse acceptée.
function strip(html)
{
var tmp = document.implementation.createHTMLDocument("New").body;
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
de cette façon, quelque chose qui court comme ça ne fera pas de mal:
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Firefox, Chromium et Explorer 9+ sont sans danger. L'Opéra Presto est encore vulnérable. Les images mentionnées dans les chaînes de caractères ne sont pas non plus téléchargées dans les requêtes HTTP de sauvegarde Chromium et Firefox.
cela devrait faire le travail sur N'importe quel environnement Javascript (NodeJS inclus).
text.replace(/<[^>]+>/g, '');
j'ai modifié la réponse de Jibberboy2000 pour inclure plusieurs formats d'étiquette <BR />
, supprimer tout ce qui se trouve à l'intérieur des étiquettes <SCRIPT>
et <STYLE>
, formater le HTML résultant en supprimant les ruptures de lignes multiples et les espaces et convertir du code codé HTML en normal. Après quelques tests, il apparaît que vous pouvez convertir la plupart des pages web complètes en texte simple où le titre de la page et le contenu sont conservés.
dans l'exemple 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>
devient
C'est mon titre
cette chaîne a le code html que je veux supprimer
dans cette ligne BBC ( http://www.bbc.co.uk ) avec lien est mentionné.
maintenant retour à "texte normal" et des trucs en utilisant
la fonction JavaScript et la page de test Regardez ceci:
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, " ()");
//-- 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;
}
il a été utilisé avec CE 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 />
une autre solution, certes moins élégante que celle de nickf ou de Shog9, serait de marcher récursivement le DOM à partir de la balise
et d'ajouter chaque noeud de texte.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;
}
si vous voulez garder les liens et la structure du contenu (h1, h2, etc), alors vous devriez vérifier TextVersionJS vous pouvez l'utiliser avec N'importe quel HTML, bien qu'il ait été créé pour convertir un courriel HTML en texte simple.
l'usage est très simple. Par exemple, dans le nœud.js:
var createTextVersion = require("textversionjs");
var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
var textVersion = createTextVersion(yourHtml);
ou dans le navigateur avec JS pur:
<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>
il fonctionne aussi avec require.js:
define(["textversionjs"], function(createTextVersion) {
var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
var textVersion = createTextVersion(yourHtml);
});
après avoir essayé toutes les réponses mentionnées la plupart sinon toutes avaient bordures cas et ne pouvait pas complètement soutenir mes besoins.
j'ai commencé à explorer comment php le fait et je suis tombé sur le php.js lib qui reproduit la méthode strip_tags ici: http://phpjs.org/functions/strip_tags /
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('');
}
rend compte de > Inside attributes et <img onerror="javascript">
dans les éléments dom nouvellement créés.
utilisation:
clean_string = stripHTML("string with <html> in it")
démo:
https://jsfiddle.net/gaby_de_wilde/pqayphzd /
démonstration de réponse sommet, de faire les choses terribles:
beaucoup de gens ont déjà répondu à cela, mais j'ai pensé qu'il pourrait être utile de partager la fonction que j'ai écrite qui supprime les balises HTML d'une chaîne, mais vous permet d'inclure un tableau de balises que vous ne voulez pas dépouillé. Il est assez court et travaille bien pour moi.
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>
j'ai fait quelques modifications au script original de Jibberboy2000 J'espère qu'il sera utile pour quelqu'un
str = '**ANY HTML CONTENT HERE**';
str=str.replace(/<\s*br\/*>/gi, "\n");
str=str.replace(/<\s*a.*href="(.*?)".*>(.*?)<\/a>/gi, " (Link->) ");
str=str.replace(/<\s*\/*.+?>/ig, "\n");
str=str.replace(/ {2,}/gi, " ");
str=str.replace(/\n+\s*/gi, "\n\n");
Voici une version qui répond à la préoccupation de sécurité 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 "";
}
}
Note, il retournera une chaîne vide si le balisage HTML N'est pas valide XML (Alias, les balises doivent être fermées et les attributs doivent être cités). Ce n'est pas idéal, mais évite la question d'avoir le potentiel d'exploiter la sécurité.
si vous n'avez pas besoin d'un balisage XML valide, Vous pouvez essayer d'utiliser:
var doc = document.implementation.createHTMLDocument("");
mais que ce n'est pas une solution parfaite pour d'autres raisons.
je pense que la façon la plus facile est d'utiliser des Expressions régulières comme quelqu'un mentionné ci-dessus. Bien qu'il n'y a pas de raison d'utiliser un tas d'entre eux. Essayez:
stringWithHTML = stringWithHTML.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");
avec jQuery vous pouvez simplement le récupérer en utilisant
$('#elementID').text()
code ci-dessous vous permet de conserver certaines balises html tout en enlevant tous les autres""
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("151900920", ) {
return allowed.indexOf('<' + .toLowerCase() + '>') > -1 ? "151900920" : '';
});
}
il est également possible d'utiliser le fantastique htmlparser2 pur JS HTML parser. Voici une démo de travail:
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 sortie sera This is a simple example.
Voir en action ici: https://tonicdev.com/jfahrenkrug/extract-text-from-html
cela fonctionne à la fois dans le noeud et le navigateur si vous empaquetez votre application web en utilisant un outil comme webpack.
j'avais juste besoin d'enlever les balises <a>
et de les remplacer par le texte du lien.
ça a l'air de bien marcher.
htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '');
htmlContent= htmlContent.replace(/<\/a>/g, '');
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
c'est une version regex, qui est plus résistante aux HTML malformés, comme:
Ouvrez les balises
Some text <img
"<", ">" à l'intérieur des attributs de la balise
Some text <img alt="x > y">
les retours à la ligne
Some <a
href="http://google.com">
le code
var html = '<br>This <img alt="a>b" \r\n src="a_b.gif" />is > \nmy<>< > <a>"text"</a'
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
j'ai moi-même créé une expression régulière de travail:
str=str.replace(/(<\?[a-z]*(\s[^>]*)?\?(>|$)|<!\[[a-z]*\[|\]\]>|<!DOCTYPE[^>]*?(>|$)|<!--[\s\S]*?(-->|$)|<[a-z?!\/]([a-z0-9_:.])*(\s[^>]*)?(>|$))/gi, '');
simple 2 ligne jquery pour supprimer le 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 réponse acceptée fonctionne très bien la plupart du temps, cependant dans IE si la chaîne html
est null
vous obtenez le "null"
(au lieu de"). Fixe:
function strip(html)
{
if (html == null) return "";
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
Utilisant Jquery:
function stripTags() {
return $('<p></p>').html(textToEscape).text()
}
input
élément soutenir une seule ligne de texte :
l'état de texte représente un contrôle d'édition de texte simple d'une ligne pour la valeur de l'élément.
function stripHtml(str) {
var tmp = document.createElement('input');
tmp.value = str;
return tmp.value;
}
mise à Jour: cela fonctionne comme prévu
function stripHtml(str) {
// Remove some tags
str = str.replace(/<[^>]+>/gim, '');
// Remove BB code
str = str.replace(/\[(\w+)[^\]]*](.*?)\[\/]/g, ' ');
// 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;
}
vous pouvez retirer en toute sécurité des balises html en utilisant l'attribut iframe sandbox .
l'idée ici est qu'au lieu d'essayer de regexer notre chaîne de caractères, nous profitons de l'analyseur natif du navigateur en injectant le texte dans un élément DOM et en questionnant la propriété textContent
/ innerText
de cet élément.
l'élément le mieux adapté pour injecter notre texte est une iframe encastrée, de cette façon nous pouvons éviter toute exécution de code arbitraire (également connu sous le nom XSS ).
L'inconvénient de cette approche est qu'elle ne fonctionne que dans les navigateurs.
voici ce que j'ai inventé (pas testé au combat):
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 || "";
};
})();
"1519190920 d'Utilisation" ( démo ):
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));
(function($){
$.html2text = function(html) {
if($('#scratch_pad').length === 0) {
$('<div id="lh_scratch"></div>').appendTo('body');
}
return $('#scratch_pad').html(html).text();
};
})(jQuery);
définissez ceci comme un plugin jquery et utilisez-le comme suit:
$.html2text(htmlContent);
pour les caractères d'évasion aussi cela fonctionnera en utilisant l'appariement des motifs:
myString.replace(/((<)|(<)(?:.|\n)*?(>)|(>))/gm, '');