从Text JavaScript中删除HTML

Bry*_*yan 603 html javascript string

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

Sho*_*og9 716

如果您在浏览器中运行,那么最简单的方法就是让浏览器为您执行此操作...

function stripHtml(html)
{
   var tmp = document.createElement("DIV");
   tmp.innerHTML = html;
   return tmp.textContent || tmp.innerText || "";
}
Run Code Online (Sandbox Code Playgroud)

注意:正如大家在评论中指出的那样,如果你不控制HTML的来源(例如,不要在任何可能来自用户输入的内容上运行),最好避免这种情况.对于这些场景,您仍然可以让浏览器为您完成工作 - 请参阅Saba关于使用现在广泛使用的DOMParser的答案.

  • 不要将此与来自不受信任来源的HTML一起使用.要了解原因,请尝试运行`strip("<img rel="nofollow noreferrer" onerror ='alert(\"可以在这里运行任意JS)"src = bogus>") (216认同)
  • 请记住,这种方法相当不一致,并且无法在某些浏览器中删除某些字符.例如,在Prototype.js中,我们使用这种方法来提高性能,但解​​决了一些不足之处 - http://github.com/kangax/prototype/blob/a223833c8b49ae55f03b1e1a3a5b7e9fb647c139/src/lang/string.js#L476 (40认同)
  • 如果html包含图像(img标签),则浏览器将请求图像.这不好. (24认同)
  • 记住,你的空白将被搞乱.我以前使用这种方法,然后出现问题,因为某些产品代码包含双重空格,在我从DIV返回innerText之后最终成为单个空格.然后,产品代码在应用程序的后期不匹配. (11认同)
  • @Magnus Smith:是的,如果空白是一个问题 - 或者真的,如果你有任何需要这个文本不直接涉及你正在使用的特定HTML DOM - 那么你最好使用其中一个解决方案在这里.这种方法的主要优点是1)微不足道,2)可以像你在*中运行的浏览器一样可靠地处理标签,空格,实体,注释等.这通常对Web客户端代码有用,但不一定适合与规则不同的其他系统进行交互. (11认同)
  • 这也将删除文本之间的任何<br />.这可以将文本连接在一起,如果<br />的前一个文本和/或下一个文本之间不应该有空格 (2认同)
  • @Ziggy:如果你需要使用JavaScript清理*不可信的HTML,你可能想从这里开始:http://stackoverflow.com/questions/295566/sanitize-rewrite-html-on-the-client-side (2认同)

nic*_*ckf 544

myString.replace(/<[^>]*>?/gm, '');
Run Code Online (Sandbox Code Playgroud)

  • @MikeSamuel我们决定这个答案吗?天真的用户在这里准备复制粘贴. (67认同)
  • 一个简单的方法是将`/<.*?>/ g`改为`/ <[^>]*>?/ g`.如果您同意,请编辑您的帖子,以便像Ribeiro先生这样的天真用户不会复制/粘贴破坏的安全建议. (31认同)
  • 非常棒,它适用于非浏览器js(如节点). (20认同)
  • @AntonioMax,我已经回答了这个问题[令人作呕(http://stackoverflow.com/a/430240/20394),但你的问题的实质,因为**安全关键代码不应该复制粘贴& .**您应该下载一个库,并使其保持最新并进行修补,以便您能够抵御最近发现的漏洞和浏览器中的更改. (15认同)
  • 不适用于`<img rel="nofollow noreferrer" src = http://www.google.com.kh/images/srpr/nav_logo27.png onload ="alert(42)"`如果您通过`document.write`注入或在通过`innerHTML`注入之前与包含`>`的字符串连接. (4认同)
  • @PerishableDave,我同意“&gt;”将留在第二个中。但这并不是注射危险。危险的发生是由于第一个中留下了`&lt;`,这导致HTML解析器处于[数据状态](http://www.w3.org/TR/html5/tokenization.html#data-状态)当第二个开始时。请注意,“&gt;”上没有数据状态的转换。 (2认同)
  • 我相信,如果给出类似 `&lt;button onClick="dostuff('&gt;');"&gt;&lt;/button&gt;` 之类的东西,我相信这也会完全混淆 假设 HTML 编写正确,您仍然需要考虑大于号可能位于属性中引用文本的某处。您还希望至少删除 `&lt;script&gt;` 标签内的所有文本。 (2认同)
  • 最好有一些解释(它处理什么情况、限制、关于正则表达式本身的解释......)和单元测试 (2认同)

Mar*_*ark 239

最简单的方法:

jQuery(html).text();
Run Code Online (Sandbox Code Playgroud)

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

  • 我们总是将jQuery用于项目,因为我们的项目总是有很多Javascript.因此我们没有添加批量,我们利用现有的API代码... (109认同)
  • 对于那些需要和OP做同样事情的人(比如我)并且不介意使用jQuery(像我一样),它仍然是一个有用的答案,更不用说,如果他们考虑使用它可能对OP有用jQuery的.该网站的重点是分享知识.请记住,没有充分理由,通过惩罚有用的答案可能会产生寒蝉效应. (99认同)
  • 如果您的某些字符串部分未包含在html标记中,那将无效.例如"<b>错误:</ b>请输入有效的电子邮件"将仅返回"错误:" (34认同)
  • 你使用它,但OP可能不会.问题是关于Javascript NOT JQuery. (30认同)
  • @Dementic令人震惊的是,我发现具有多个答案的线程是最有用的,因为通常次要答案符合我的确切需求,而主要答案符合一般情况. (26认同)
  • 上面Mike Samuel的评论也适用于此.不要将此与来自不受信任来源的HTML一起使用.要了解原因,请尝试运行`jQuery("<img rel="nofollow noreferrer" onerror ='alert(\"可以在这里运行任意JS)"src = bogus>").text();` (15认同)
  • 你应该将它包装在一个HTML元素中,使其对文本字符串也有效:`$('<i>').html(html).text()`.这也将在node.js中后端工作. (13认同)
  • 也适用于角度:`angular.element(html).text();`(实际调用委托给jquery lite) (3认同)
  • 如果您使用的是CKEditor,那么您已经加载了jQuery.但要获得所有实际字符以获得准确计数,您需要修剪结果:chars = jQuery(editor.getData()).text().trim()) (2认同)
  • @dementic:在标签中还有jQuery,所以我不明白为什么这不是一个有效的答案.. + 1帮了我 (2认同)
  • 如果'html'具有纯字符串,则无效.例如`jQuery("<a> abc </a>").text()`将输出"abc".但是`jQuery("abc").text()`将输出""(预期abc) (2认同)

Sab*_*baz 93

我想分享一下Shog9批准的答案的编辑版本.


正如Mike Samuel指出的那样,该函数可以执行内联javascript代码.
Shog9说"让浏览器为你做这件事......"是对的.

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

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

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

strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Run Code Online (Sandbox Code Playgroud)

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

strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")
Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的答案,因为这是最安全、最快的方法 (6认同)
  • 值得补充的是,该解决方案仅在浏览器中有效。 (2认同)
  • 另外,它不会尝试[使用正则表达式解析html](/sf/answers/121271811/) (2认同)

use*_*305 53

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

jQuery(html).text();

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

使用:

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

代替.

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

  • 或者`$("<p>").html(html).text();` (12认同)
  • 这仍然执行可能危险的代码`jQuery('<span> Text :) <img rel="nofollow noreferrer" src ="a"onerror ="alert(1)"> </ span>').text()` (4认同)

小智 38

转换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, "");
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

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

希望您觉得这个有帮助.


Jan*_*hou 32

对已接受答案的改进.

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

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

strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Run Code Online (Sandbox Code Playgroud)

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


Kar*_*l.S 20

这应该在任何Javascript环境(包括NodeJS)上完成. __CODE__

  • `&lt;html&gt; &lt;style ..&gt; * {font-family:comic-sans;} &lt;/ style&gt;某些文本&lt;/ html&gt;` (3认同)

Ele*_*wen 15

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

在简单的例子中,

<!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>
Run Code Online (Sandbox Code Playgroud)

这是我的头衔

这个字符串有我要删除的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;
}
Run Code Online (Sandbox Code Playgroud)

它与此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 />
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个解决方案,因为它可以处理 html 特殊字符...但仍然不够...对我来说最好的答案是处理所有这些字符。(这可能就是 jquery 所做的)。 (2认同)
  • 我认为`/ <p.*>/gi`应该是`/ <p.*?>/gi`. (2认同)

heg*_*mon 13

var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
Run Code Online (Sandbox Code Playgroud)

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

未封闭的标签

Some text <img

标签属性中包含"<",">"

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

换行

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, "");
Run Code Online (Sandbox Code Playgroud)

  • 我个人最喜欢的,我还会添加删除换行符,例如: `const deTagged = myString.replace(/&lt;\/?("[^"]*"|'[^']*'|[^&gt;])*( &gt;|$)/g, ''); const deNewlined = deTagged.replace(/\n/g, '');` (2认同)

Ank*_*wat 8

const htmlParser= new DOMParser().parseFromString("<h6>User<p>name</p></h6>" , 'text/html');
const textString= htmlParser.body.textContent;
console.log(textString)
Run Code Online (Sandbox Code Playgroud)


Bry*_*yan 7

另一个公认的不如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;
}
Run Code Online (Sandbox Code Playgroud)

  • 让人惊讶.如果您要从字符串中创建DOM树,那么只需使用shog的方式! (2认同)

gyu*_*eth 7

如果你想保留链接和内容的结构(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);
Run Code Online (Sandbox Code Playgroud)

或者在浏览器中使用纯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>
Run Code Online (Sandbox Code Playgroud)

它也适用于require.js:

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


Ana*_*tol 7

来自 CSS 技巧:

https://css-tricks.com/snippets/javascript/strip-html-tags-in-javascript/

const originalString = `
  <div>
    <p>Hey that's <span>somthing</span></p>
  </div>
`;

const strippedString = originalString.replace(/(<([^>]+)>)/gi, "");

console.log(strippedString);
Run Code Online (Sandbox Code Playgroud)


Joh*_*rug 6

也可以使用神奇的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('');
Run Code Online (Sandbox Code Playgroud)

输出将是This is a simple example.

在这里查看它的实际效果: https: //tonicdev.com/jfahrenkrug/extract-text-from-html

如果您使用 webpack 等工具打包 Web 应用程序,那么这在节点和浏览器中都适用。


Har*_*ens 5

很多人已经回答了这个问题,但我认为分享我编写的函数可能会很有用,该函数从字符串中剥离 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>
Run Code Online (Sandbox Code Playgroud)


Aks*_*kar 5

为了更简单的解决方案,试试这个 => https://css-tricks.com/snippets/javascript/strip-html-tags-in-javascript/

var StrippedString = OriginalString.replace(/(<([^>]+)>)/ig,"");
Run Code Online (Sandbox Code Playgroud)