从文本JavaScript中剥离超文本标记语言

有没有一种简单的方法可以在JavaScript中获取一串html并去掉html?

845120 次浏览
myString.replace(/<[^>]*>?/gm, '');

如果您在浏览器中运行,那么最简单的方法就是让浏览器为你做…

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

注意:正如人们在评论中指出的,如果您不控制超文本标记语言的来源,最好避免这种情况(例如,不要在任何可能来自用户输入的东西上运行它)。对于这些情况,您可以仍然让浏览器为您完成工作-查看Saba关于使用现在广泛使用的DOMParser的回答

另一个,公认的不那么优雅的解决方案是,从标记开始递归遍历DOM并附加每个文本节点。

var bodyContent = document.getElementsByTagName('body')[0];var result = appendTextNodes(bodyContent);
function appendTextNodes(element) {var text = '';
// Loop through the childNodes of the passed in elementfor (var i = 0, len = element.childNodes.length; i < len; i++) {// Get a reference to the current childvar node = element.childNodes[i];// Append the node's value if it's a text nodeif (node.nodeType == 3) {text += node.nodeValue;}// Recurse through the node's children, if there are anyif (node.childNodes.length > 0) {appendTextNodes(node);}}// Return the final resultreturn text;}

转换纯文本电子邮件的超文本标记语言,保持超链接(href)完好无损

上述功能张贴的缺氧工作正常,但我后的东西,基本上会转换超文本标记语言在Web RichText编辑器中创建(例如FCKEditor)和清除所有的超文本标记语言,但留下所有的链接,因为我想要的超文本标记语言和纯文本版本,以帮助创建正确的部分STMP电子邮件(超文本标记语言和纯文本)。

经过长时间的谷歌搜索,我和我的同事们使用Javascript中的regex引擎想出了这个:

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 removeLink Number 1 -> BBC (Link->http://www.bbc.co.uk)  Link Number 1

Now back to normal text and stuff

正如你所看到的,所有的超文本标记语言都被删除了,链接仍然保留,超链接文本仍然完好无损。我还用\n(换行符)替换了<p><br>标签,以便保留某种视觉格式。

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

希望你觉得这个有用。

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

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

我做了一些修改原始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");

最简单的方法:

jQuery(html).text();

它从一个html字符串中检索所有文本。

我修改了Jibberboy2000的答案以包含几种<BR />标记格式,删除<SCRIPT><STYLE>标记中的所有内容,通过删除多个换行符和空格来格式化生成的超文本标记语言,并将一些超文本标记语言编码的代码转换为普通代码。经过一些测试,您似乎可以将大部分完整网页转换为保留页面标题和内容的简单文本。

在简单的例子中,

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

成为

这是我的头衔

这个字符串有我想删除的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 breakreturnText=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 themreturnText=returnText.replace(/<p.*>/gi, "\n");returnText=returnText.replace(/<a.*href="(.*?)".*>(.*?)<\/a>/gi, " $2 ($1)");
//-- remove all inside SCRIPT and STYLE tagsreturnText=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 elsereturnText=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,'>');
//-- returndocument.getElementById("output").value = returnText;}

它与这种超文本标记语言一起使用:

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

将其定义为一个jQuery插件,并按如下方式使用它:

$.html2text(htmlContent);

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

请注意,如果超文本标记语言不是有效的XML(即,必须关闭标签并且必须引用属性),它将返回一个空字符串。这并不理想,但确实避免了具有安全漏洞利用潜力的问题。

如果您不需要有效的XML标记,您可以尝试使用:

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

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

使用jQuery,您可以简单地使用

$('#elementID').text()

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

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

作为jQuery方法的扩展,如果您的字符串可能不包含超文本标记语言(例如,如果您试图从表单字段中删除超文本标记语言)

jQuery(html).text();

如果没有超文本标记语言,将返回空字符串

用途:

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

相反。

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

简单的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 textconsole.log(text);//check the data in your console
cj("#text_area_id").val(text);//set your content to text area using text_area_id

对已接受答案的改进。

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保存超文本传输协议请求中下载。

我只需要去掉<a>标签并用链接的文本替换它们。

这似乎工作得很好。

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

在尝试了所有提到的答案之后,如果不是所有的答案都有边缘情况,不能完全支持我的需求。

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

下面的代码允许您保留一些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 : '';});}
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")

demo:

顶级答案做可怕的事情的演示:

也可以使用梦幻般的htmlparser2纯JS超文本标记语言解析器。这是一个工作演示:

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应用程序,这在节点和浏览器中都有效。

接受的答案大部分都很好,但是在IE中,如果html字符串是null,你会得到"null"(而不是")。修正:

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

如果你想保留链接和内容的结构(h1,h2等),那么你应该检查文本版本你可以将它与任何超文本标记语言一起使用,尽管它是为了将超文本标记语言电子邮件转换为纯文本而创建的。

用法非常简单。例如在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);});

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

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

使用JQuery:

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

这应该在任何Javascript环境(包括NodeJS)上完成工作。

    const text = `<html lang="en"><head><style type="text/css">*{color:red}</style><script>alert('hello')</script></head><body><b>This is some text</b><br/><body></html>`;    
// Remove style tags and contenttext.replace(/<style[^>]*>.*<\/style>/gm, '')// Remove script tags and content.replace(/<script[^>]*>.*<\/script>/gm, '')// Remove all opening, closing and orphan HTML tags.replace(/<[^>]+>/gm, '')// Remove leading spaces and repeated CR/LF.replace(/([\r\n]+ +)+/gm, '');

很多人已经回答了这个问题,但我认为分享我写的函数可能会有用,该函数从字符串中剥离超文本标记语言标签,但允许您包含一系列不想剥离的标签。它非常短,对我来说一直很有用。

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>

input元素仅支持一行文本

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

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

更新时间:如预期的那样工作

function stripHtml(str) {// Remove some tagsstr = str.replace(/<[^>]+>/gim, '');
// Remove BB codestr = str.replace(/\[(\w+)[^\]]*](.*?)\[\/\1]/g, '$2 ');
// Remove html and line breaksconst div = document.createElement('div');div.innerHTML = str;
const input = document.createElement('input');input.value = div.textContent || div.innerText || '';
return input.value;}

我想分享Shog9的认可答案的编辑版本。


正如迈克·塞缪尔所指出的注释,该函数可以执行内联javascript代码。
但是Shog9在说“让浏览器为你做……”时是正确的。

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

function strip(html){let 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'>")
function strip_html_tags(str){if ((str===null) || (str===''))return false;elsestr = str.toString();return str.replace(/<[^>]*>/g, '');}
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");

这是一个正则表达式版本,它对格式错误的超文本标记语言更具弹性,例如:

未关闭的标签

Some text <img

"<;", ">" 标签属性

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

新线

一些

该代码

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

https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML

var div = document.getElementsByTagName('div');for (var i=0; i<div.length; i++) {div[i].insertAdjacentHTML('afterend', div[i].innerHTML);document.body.removeChild(div[i]);}

使用jQuery剥离html的更安全方法是首先使用jQuery.parse超文本标记语言创建DOM,忽略任何脚本,然后让jQuery构建元素,然后仅检索文本。

function stripHtml(unsafe) {return $($.parseHTML(unsafe)).text();}

可以安全地从:

<img src="unknown.gif" onerror="console.log('running injections');">

和其他利用。

nJoy!

方法一:

function cleanHTML(str){str.replace(/<(?<=<)(.*?)(?=>)>/g, '&lt;$1&gt;');}
function uncleanHTML(str){str.replace(/&lt;(?<=&lt;)(.*?)(?=&gt;)&gt;/g, '<$1>');}

方法二:

function cleanHTML(str){str.replace(/</g, '&lt;').replace(/>/g, '&gt;');}
function uncleanHTML(str){str.replace(/&lt;/g, '<').replace(/&gt;/g, '>');}

另外,不要忘记,如果用户碰巧发布了数学注释(ex: 1 < 2),你不想删除整个注释。浏览器(仅测试了chrome)不会将Unicode作为html标签运行。如果您将字符串中的所有<替换为&lt;每个软件,Unicode将在不运行任何html的情况下将<显示为文本。我推荐方法2. jQuery也运行良好$('#element').text();

对于更简单的解决方案,请尝试此=>https://css-tricks.com/snippets/javascript/strip-html-tags-in-javascript/

var StrippedString = OriginalString.replace(/(<([^>]+)>)/ig,"");

从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);

var STR='<Your HTML STRING>''var HTMLParsedText="";var resultSet =  STR.split('>')var resultSetLength =resultSet.lengthvar counter=0while(resultSetLength>0){if(resultSet[counter].indexOf('<')>0){var value = resultSet[counter];value=value.substring(0, resultSet[counter].indexOf('<'))if (resultSet[counter].indexOf('&')>=0 && resultSet[counter].indexOf(';')>=0) {value=value.replace(value.substring(resultSet[counter].indexOf('&'), resultSet[counter].indexOf(';')+1),'')}}if (value){value = value.trim();if(HTMLParsedText === ""){HTMLParsedText = value;}else{if (value) {HTMLParsedText = HTMLParsedText + "\n" + value;}}value='';}counter= counter+1;resultSetLength=resultSetLength-1;}console.log(HTMLParsedText);

如果您不想为此创建DOM(也许您不在浏览器上下文中),您可以使用条纹标签 npm包。

import striptags from 'striptags'; //ES6 <-- pick oneconst striptags = require('striptags'); //ES5 <-- pick one
striptags('<p>An HTML string</p>');

这个包非常适合剥离超文本标记语言:https://www.npmjs.com/package/string-strip-html

它适用于浏览器和服务器(例如Node.js)。

const getTextFromHtml = (t) =>t?.split('>')?.map((i) => i.split('<')[0]).filter((i) => !i.includes('=') && i.trim()).join('');
const test = '<p>This <strong>one</strong> <em>time</em>,</p><br /><blockquote>I went to</blockquote><ul><li>band <a href="https://workingclasshistory.com" rel="noopener noreferrer" target="_blank">camp</a>…</li></ul><p>I edited this as a reviewer just to double check</p>'
getTextFromHtml(test)// 'This onetime,I went toband camp…I edited this as a reviewer just to double check'
const strip=(text) =>{return (new DOMParser()?.parseFromString(text,"text/html"))?.body?.textContent}
const value=document.getElementById("idOfEl").value
const cleanText=strip(value)

正如其他人所建议的,我建议尽可能使用DOMParser

然而,如果你碰巧在节点/JS Lambda中工作,或者DOMParser不可用,我想出了下面的正则表达式来匹配之前回答/评论中提到的大多数场景。它不匹配$gt;$lt;,因为其他人可能担心,但应该捕获几乎任何其他场景。

const dangerousText = '?';const htmlTagRegex = /<\/?([a-zA-Z]\s?)*?([a-zA-Z]+?=\s?".*")*?([\s/]*?)>/gi;const sanitizedText = dangerousText.replace(htmlTagRegex, '');

这可能很容易简化,但它应该适用于大多数情况。希望它能帮助某人。

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

您可以使用以下正则表达式去掉所有html标签:/<(.|\n)*?>/g

示例:

let str = "<font class=\"ClsName\">int[0]</font><font class=\"StrLit\">()</font>";console.log(str.replace(/<(.|\n)*?>/g, ''));

输出:

int[0]()

一个非常好的库是sanitize-html,它是一个纯JavaScript函数,它可以在任何环境中提供帮助。

我的案例是在React Native上,我需要从给定的文本中删除所有超文本标记语言标签。所以我创建了这个包装器函数:

import sanitizer from 'sanitize-html';
const textSanitizer = (textWithHTML: string): string =>sanitizer(textWithHTML, {allowedTags: [],});
export default textSanitizer;

现在通过使用我的textSanitizer,我可以得到纯文本内容。