Supprimer HTML du texte JavaScript

Est-il un moyen facile de prendre une chaîne de html en JavaScript et dépouiller le html?

507
demandé sur Gideon 2009-05-05 02:39:54

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 .

633
répondu Shog9 2018-01-26 16:15:44
myString.replace(/<(?:.|\n)*?>/gm, '');
433
répondu nickf 2011-11-16 10:12:35

la manière la plus simple:

jQuery(html).text();

qui récupère tout le texte d'une chaîne de caractères html.

224
répondu Mark 2012-08-24 18:18:28

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.

49
répondu user999305 2017-06-18 13:06:14

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'>")
45
répondu Saba 2017-12-06 10:15:15

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.

35
répondu Jibberboy2000 2015-06-18 14:21:56

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.

26
répondu Janghou 2018-09-19 15:26:03

cela devrait faire le travail sur N'importe quel environnement Javascript (NodeJS inclus). text.replace(/<[^>]+>/g, '');

16
répondu Karl.S 2017-01-20 05:49:54

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 &quot;normal text&quot; and stuff using &lt;html encoding&gt;                 
    </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(/&nbsp;/gi," ");
    returnText=returnText.replace(/&amp;/gi,"&");
    returnText=returnText.replace(/&quot;/gi,'"');
    returnText=returnText.replace(/&lt;/gi,'<');
    returnText=returnText.replace(/&gt;/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 />
15
répondu Elendurwen 2017-05-23 11:54:58

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;
}
7
répondu Bryan 2009-05-04 23:14:30

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);
});
5
répondu gyula.nemeth 2016-08-04 07:38:10

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 /

4
répondu Deminetix 2015-06-11 22:06:11
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:

https://jsfiddle.net/gaby_de_wilde/6f0jymL6/1 /

4
répondu user40521 2016-03-27 07:29:37

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>
4
répondu Harry Stevens 2017-01-27 06:55:53

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");
3
répondu Jaxolotl 2011-10-04 14:02:41

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.

3
répondu Jeremy Johnstone 2012-07-12 21:10:24

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, "");
2
répondu Byron Carasco 2011-01-10 05:40:34

avec jQuery vous pouvez simplement le récupérer en utilisant

$('#elementID').text()
2
répondu ianaz 2012-09-03 15:03:35

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" : '';
      });
}
2
répondu aWebDeveloper 2015-07-14 12:56:53

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.

2
répondu Johannes Fahrenkrug 2015-12-29 19:11:59

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, '');
2
répondu FrigginGlorious 2016-01-06 18:57:29
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, "");
2
répondu hegemon 2018-07-06 10:39:57

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, ''); 
1
répondu MarekJ47 2012-11-09 16:06:12

simple 2 ligne jquery pour supprimer le html.

 var content = "<p>checking the html source&nbsp;</p><p>&nbsp;
  </p><p>with&nbsp;</p><p>all</p><p>the html&nbsp;</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
1
répondu Developer 2013-07-05 09:18:26

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 || "";
}
1
répondu basarat 2016-05-27 00:12:48

Utilisant Jquery:

function stripTags() {
    return $('<p></p>').html(textToEscape).text()
}
1
répondu math2001 2016-12-09 08:41:42

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;
}
1
répondu Mike 2017-10-27 02:13:08

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));
1
répondu Etienne Martin 2018-04-04 18:20:29
    (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);
0
répondu Shiv Shankar 2012-03-16 06:25:57

pour les caractères d'évasion aussi cela fonctionnera en utilisant l'appariement des motifs:

myString.replace(/((&lt)|(<)(?:.|\n)*?(&gt)|(>))/gm, '');
0
répondu Abhishek Dhanraj Shahdeo 2016-11-16 06:00:59