从文本JavaScript中去除HTML
有没有一种简单的方法来获取JavaScript的string和去除HTML?
如果你正在浏览器中运行,那么最简单的方法就是让浏览器为你做这件事。
function strip(html) { var tmp = document.createElement("DIV"); tmp.innerHTML = html; return tmp.textContent || tmp.innerText || ""; }
myString.replace(/<(?:.|\n)*?>/gm, '');
最简单的方法:
jQuery(html).text();
这将从一个htmlstring中检索所有的文本。
作为jQuery方法的扩展,如果你的string可能不符合HTML(例如,如果你正试图从表单域中删除HTML)
jQuery(html).text();
如果没有html,将返回一个空string
使用:
jQuery('<p>' + html + '</p>').text();
代替。
更新:正如已经在评论中指出的那样,在某些情况下,如果html
的值可能受到攻击者的影响,这个解决scheme将执行包含在html
javascript,使用不同的解决scheme。
为纯文本电子邮件转换保持超链接(一个href)完整的HTML
上面的函数发布低氧化工作正常,但我后面的东西,将基本上转换在一个Web RichText编辑器(例如FCKEditor)中创build的HTML,并清除所有的HTML,但离开所有的链接,因为我希望HTML和纯文本版本,以帮助创buildSTMP电子邮件(包括HTML和纯文本)的正确部分。
经过一段时间的search谷歌自己和我的同事想出了这个在Javascript中使用正则expression式引擎:
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
variables是这样开始的:
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
(换行符char)replace了<p>
和<br>
标签,以保留某种可视格式。
要更改链接格式(例如BBC (Link->http://www.bbc.co.uk)
),只需编辑$2 (Link->$1)
,其中$1
是href URL / URI, $2
是超链接文本。 直接在纯文本正文中的链接大多数SMTP邮件客户端转换这些,使用户有能力点击它们。
希望你觉得这个有用。
对早期答案的改进。
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仍然是脆弱的。 在string中提到的图像也不会下载到Chromium和Firefox保存http请求。
我改变了Jibberboy2000的答案 ,包括几个<BR />
标签格式,删除<SCRIPT>
和<STYLE>
标签内的所有内容,通过删除多个换行符和空格来格式化HTML,并将一些HTML编码的代码转换成普通格式。 经过一些testing后,似乎可以将大部分完整的网页转换为保留页面标题和内容的简单文本。
在简单的例子中,
<!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>
变
这是我的标题
这个string有我想要删除的HTML代码
在这一行BBC( http://www.bbc.co.uk )链接被提及。
现在回到“正常文本”和东西使用
JavaScript函数和testing页面看起来如下:
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(/ /gi," "); returnText=returnText.replace(/&/gi,"&"); returnText=returnText.replace(/"/gi,'"'); returnText=returnText.replace(/</gi,'<'); returnText=returnText.replace(/>/gi,'>'); //-- return document.getElementById("output").value = returnText; }
它与这个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 />
这应该做任何Javascript环境(包括NodeJS)的工作。 text.replace(/<[^>]+>/g, '');
另外一个比nickf或者Shog9更不优雅的解决scheme,是recursion地从<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; }
如果你想保持链接和内容的结构(h1,h2等),那么你应该检查TextVersionJS你可以使用任何HTML,尽pipe它被创build为将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); });
在尝试了所有提到的答案之后,如果不是所有答案都是有边界的,并不能完全支持我的需求的话。
我开始探索php是如何实现的,并遇到了复制strip_tags方法的php.js库: 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(''); }
在新创build的dom元素中用于内部属性和<img onerror="javascript">
。
用法:
clean_string = stripHTML("string with <html> in it")
演示:
https://jsfiddle.net/gaby_de_wilde/pqayphzd/
顶级答案演示做可怕的事情:
我对原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");
这里有一个地址@ 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(也就是说,标记必须closures并且属性必须被引用),它将返回一个空string。 这并不理想,但确实避免了具有安全漏洞利用潜力的问题。
如果没有有效的XML标记是你的要求,你可以尝试使用:
var doc = document.implementation.createHTMLDocument("");
但是由于其他原因,这不是一个完美的解决scheme。
很多人已经回答了这个问题,但是我认为分享我写的function可以从string中去掉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>
我认为最简单的方法就是像上面提到的那样使用正则expression式。 虽然没有理由使用一堆。 尝试:
stringWithHTML = stringWithHTML.replace(/<\/?[az][a-z0-9]*[^<>]*>/ig, "");
使用jQuery,您可以简单地使用它来检索它
$('#elementID').text()
下面的代码允许你保留一些html标签,同时剥离所有其他的标签
function strip_tags(input, allowed) { allowed = (((allowed || '') + '') .toLowerCase() .match(/<[az][a-z0-9]*>/g) || []) .join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>) var tags = /<\/?([az][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 : ''; }); }
也可以使用奇妙的htmlparser2纯JS HTMLparsing器。 这是一个工作演示:
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应用程序,它可以在节点和浏览器中工作。
我只需要<a>
标签,并将其replace为链接的文本。
这似乎很好。
htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, ''); htmlContent= htmlContent.replace(/<\/a>/g, '');
我自己创build了一个工作正则expression式:
str=str.replace(/(<\?[az]*(\s[^>]*)?\?(>|$)|<!\[[az]*\[|\]\]>|<!DOCTYPE[^>]*?(>|$)|<!--[\s\S]*?(-->|$)|<[az?!\/]([a-z0-9_:.])*(\s[^>]*)?(>|$))/gi, '');
简单的2行jquery去掉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
接受的答案工作正常,但在IE浏览器,如果html
string为null
你会得到"null"
(而不是“)。 固定:
function strip(html) { if (html == null) return ""; var tmp = document.createElement("DIV"); tmp.innerHTML = html; return tmp.textContent || tmp.innerText || ""; }
使用Jquery:
function stripTags() { return $('<p></p>').html(textToEscape).text() }
我想分享Shog9批准的答案的编辑版本。
正如Mike Samuel评论的那样,该函数可以执行内联JavaScript代码。
但是Shog9在说“让浏览器为你做…”时是正确的。
所以..在这里我的编辑版本的他的答案,使用DOMParser :
function strip(html){ var doc = new DOMParser().parseFromString(html, 'text/html'); return doc.body.textContent || ""; }
这里的代码来testing内联的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($){ $.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);
对于转义字符也可以使用模式匹配:
myString.replace(/((<)|(<)(?:.|\n)*?(>)|(>))/gm, '');
input
元素只支持一行文字 :
文本状态表示元素值的单行纯文本编辑控件。
function stripHtml(str) { var tmp = document.createElement('input'); tmp.value = str; return tmp.value; }
更新:这按预期工作
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; }
在我的情况下$(".someClass").prop("innerText")
就足够了。
function stripMarkup(ml) { var i, qx=false, it=false; var os="",c; for( i=0 i<ml.length; i++ ) { c= ml.substr(i,1); if( !it ) { if( c == "<" ) { it=true; } else { os += c; } } else { if( qx !== false ) { if( c == qx ) { qx=false; } } else if( c == "'" || c == '"' ) { qx = c; } else if( c == "\\" ) { if( ml.substr(i+1,1) == qx ) i++; // bwahahahhaHA } else if( c == ">" ) { it = false; } continue; } } return os; }