首页 文章

从Text JavaScript中删除HTML

提问于
浏览
517

有一种简单的方法可以在JavaScript中获取一串html并删除html吗?

30 回答

  • 4

    这应该在任何Javascript环境(包括NodeJS)上完成 . text.replace(/<[^>]+>/g, '');

  • 224

    我只需要删除 <a> 标签并将其替换为链接文本 .

    这似乎很有效 .

    htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '');
    htmlContent= htmlContent.replace(/<\/a>/g, '');
    
  • 15

    使用Jquery:

    function stripTags() {
        return $('<p></p>').html(textToEscape).text()
    }
    
  • 1

    我想分享Shog9's approved answer的编辑版本 .


    正如 Mike Samuel 指出评论,该函数可以执行内联javascript代码 .
    Shog9 在说"let the browser do it for you..."时是对的

    所以...这里是我编辑的版本,使用DOMParser

    function strip(html){
       var doc = new DOMParser().parseFromString(html, 'text/html');
       return doc.body.textContent || "";
    }
    

    这里是测试内联javascript的代码:

    strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
    

    此外,它不会在解析时请求资源(如图像)

    strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")
    
  • 5

    我更改Jibberboy2000's answer以包含多个 <BR /> 标记格式,删除 <SCRIPT><STYLE> 标记内的所有内容,通过删除多个换行符和空格格式化生成的HTML并将一些HTML编码的代码转换为正常 . 经过一些测试后,您可以将大多数完整网页转换为简单文本,其中保留页面 Headers 和内容 .

    在简单的例子中,

    <!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.
    Now back to &quot;normal text&quot; and stuff using &lt;html encoding&gt; </center> </body> </html>

    这是我的 Headers 这个字符串有html代码我要删除在这一行BBC(http://www.bbc.co.uk)与链接被提到 . 现在回到“普通文本”和东西使用

    JavaScript函数和测试页面看起来像这样:

    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(/&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;
    }
    

    它与此HTML一起使用:

    <textarea id="input" style="width: 400px; height: 300px;"></textarea>
    <button onclick="convertHtmlToText()">CONVERT</button>
    <textarea id="output" style="width: 400px; height: 300px;"></textarea>
  • 0
    (function($){
            $.html2text = function(html) {
                if($('#scratch_pad').length === 0) {
                    $('<div id="lh_scratch"></div>').appendTo('body');  
                }
                return $('#scratch_pad').html(html).text();
            };
    
        })(jQuery);
    

    将其定义为jquery插件并使用如下:

    $.html2text(htmlContent);
    
  • 5
    var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
    

    这是一个正则表达式版本,它对格式错误的HTML更具弹性,例如:

    Unclosed tags

    Some text <img

    "<", ">" inside tag attributes

    Some text <img alt="x > y">

    Newlines

    Some <a href="http://google.com">

    代码

    var html = '<br>This <img alt="a>b" \r\n src="a_b.gif" />is > \nmy<>< > <a>"text"</a'
    var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
    
  • 1

    我自己创建了一个正则表达式:

    str=str.replace(/(<\?[a-z]*(\s[^>]*)?\?(>|$)|<!\[[a-z]*\[|\]\]>|<!DOCTYPE[^>]*?(>|$)|<!--[\s\S]*?(-->|$)|<[a-z?!\/]([a-z0-9_:.])*(\s[^>]*)?(>|$))/gi, '');
    
  • 4

    在尝试了所有提到的答案后,如果不是所有答案都有边缘情况,并且无法完全支持我的需求 .

    我开始探索php如何做到这一点并遇到了php.js lib,它在这里复制了strip_tags方法:http://phpjs.org/functions/strip_tags/

  • 2

    我对原始的Jibberboy2000脚本做了一些修改希望它对某人有用

    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");
    
  • 1

    这是一个解决@ 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 "";
       }
    }
    

    注意,如果HTML标记不是有效的XML,它将返回一个空字符串(也就是说,必须关闭标记并且必须引用属性) . 这不是理想的,但确实避免了具有安全漏洞利用的问题 .

    如果没有有效的XML标记是您的要求,您可以尝试使用:

    var doc = document.implementation.createHTMLDocument("");
    

    但由于其他原因,这不是一个完美的解决方案 .

  • 35

    接受的答案大多数工作正常,但是在IE中,如果 html 字符串是 null ,则得到 "null" (而不是'') . 固定:

    function strip(html)
    {
       if (html == null) return "";
       var tmp = document.createElement("DIV");
       tmp.innerHTML = html;
       return tmp.textContent || tmp.innerText || "";
    }
    
  • 30

    很多人已经回答了这个问题,但我认为分享我编写的从字符串中删除HTML标记但允许你包含一些你不想删除的标记的函数可能很有用 . 它非常简短,一直很适合我 .

    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>
    
  • 2

    简单的2行jquery去除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
    
  • 16

    另一个公认的不如nickf或Shog9的优雅解决方案是从<body>标签开始递归遍历DOM并附加每个文本节点 .

    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;
    }
    
  • 4
    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('');
    }
    

    在新创建的dom元素中考虑>内部属性和 <img onerror="javascript"> .

    用法:

    clean_string = stripHTML("string with <html> in it")
    

    演示:

    https://jsfiddle.net/gaby_de_wilde/pqayphzd/

    做出可怕事情的最佳答案演示:

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

  • 1

    也可以使用梦幻般的htmlparser2纯JS HTML解析器 . 这是一个有效的演示:

    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('');
    

    输出将是 This is a simple example.

    在这里看到它:https://tonicdev.com/jfahrenkrug/extract-text-from-html

    如果您使用webpack等工具打包Web应用程序,这在节点和浏览器中都有效 .

  • 1

    对已接受答案的改进 .

    function strip(html)
    {
       var tmp = document.implementation.createHTMLDocument("New").body;
       tmp.innerHTML = html;
       return tmp.textContent || tmp.innerText || "";
    }
    

    这样运行的东西不会造成伤害:

    strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
    

    Firefox,Chromium和Explorer 9都很安全 . Opera Presto仍然很脆弱 . 此外,字符串中提到的图像不会在Chromium和Firefox中下载,也不会保存http请求 .

  • 3
    myString.replace(/<(?:.|\n)*?>/gm, '');
    
  • 2

    转换HTML用于纯文本电子邮件,保持超链接(a href)完好无损

    由hypoxide发布的上述函数工作正常,但我之前基本上转换了在Web RichText编辑器(例如FCKEditor)中创建的HTML并清除了所有HTML,但由于我想要HTML和纯文本版本,以帮助创建STMP电子邮件的正确部分(HTML和纯文本) .

    经过很长一段时间搜索谷歌本人和我的同事在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, "");
    

    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>
    

    然后在代码运行后它看起来像这样: -

    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
    

    正如您所看到的,已删除所有HTML并且已使用超链接保持链接文字仍然完好无损 . 我还用 \n (换行符号)替换了 <p><br> 标签,以便保留某种可视格式 .

    要更改链接格式(例如 BBC (Link->http://www.bbc.co.uk) ),只需编辑 $2 (Link->$1) ,其中 $1 是href URL / URI, $2 是超链接文本 . 通过直接在纯文本正文中的链接,大多数SMTP邮件客户端都会转换这些链接,以便用户可以单击它们 .

    希望您觉得这个有帮助 .

  • 52

    最简单的方法:

    jQuery(html).text();
    

    它从一串html中检索所有文本 .

  • 0

    使用jQuery,您只需使用即可检索它

    $('#elementID').text()
    
  • 7

    作为jQuery方法的扩展,如果您的字符串可能不是contian HTML(例如,如果您尝试从表单字段中删除HTML)

    jQuery(html).text();

    如果没有html,将返回一个空字符串

    使用:

    jQuery('<p>' + html + '</p>').text();

    代替 .

    Update: 正如评论中指出的那样,在某些情况下,如果 html 的值可能会受到攻击者的影响,则此解决方案将执行 html 中包含的javascript,使用不同的解决方案 .

  • 2

    我认为最简单的方法就是像上面提到的那样使用正则表达式 . 虽然没有理由使用它们 . 尝试:

    stringWithHTML = stringWithHTML.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");
    
  • 1

    您可以使用iframe sandbox attribute安全地剥离html标签 .

    这里的想法是,我们不是试图正则表达我们的字符串,而是通过将文本注入DOM元素然后查询该元素的 textContent / innerText 属性来利用浏览器的本机解析器 .

    注入文本的最适合的元素是沙盒iframe,这样我们就可以防止任意代码执行(也称为XSS) .

    这种方法的缺点是它只适用于浏览器 .

    这是我想出的(没有经过实战考验):

    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 || "";
      };
    })();
    

    Usage (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));
    
  • 2

    对于转义字符,这也可以使用模式匹配:

    myString.replace(/((&lt)|(<)(?:.|\n)*?(&gt)|(>))/gm, '');
    
  • 643

    如果您在浏览器中运行,那么最简单的方法就是let the browser do it for you...

    function strip(html)
    {
       var tmp = document.createElement("DIV");
       tmp.innerHTML = html;
       return tmp.textContent || tmp.innerText || "";
    }
    

    注意:正如大家在评论中指出的那样,如果你不想在任何可能来自用户输入的内容上运行此操作,最好避免这种情况 . 对于这些场景,您仍然可以让浏览器为您完成工作 - see Saba's answer on using the now widely-available DOMParser .

  • 446

    如果你想保留链接和内容的结构(h1,h2等),你应该看看TextVersionJS你可以将它用于任何HTML,虽然它是为了将HTML电子邮件转换为纯文本而创建的 .

    用法很简单 . 例如在node.js中:

    var createTextVersion = require("textversionjs");
    var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
    
    var textVersion = createTextVersion(yourHtml);
    

    或者在浏览器中使用纯js:

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

    它也适用于require.js:

    define(["textversionjs"], function(createTextVersion) {
      var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
      var textVersion = createTextVersion(yourHtml);
    });
    
  • 3

    input element support only one line text

    文本状态表示元素值的单行纯文本编辑控件 .

    function stripHtml(str) {
      var tmp = document.createElement('input');
      tmp.value = str;
      return tmp.value;
    }
    

    Update: 这按预期工作

    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;
    }
    
  • 50

    下面的代码允许您保留一些html标签,同时剥离所有其他标签

    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 : '';
          });
    }
    

相关问题