从文本JavaScript中剥离HTML
有没有一种简单的方法可以在JavaScript中提取html字符串并去掉html 如果您在浏览器中运行,那么最简单的方法就是从文本JavaScript中剥离HTML,javascript,html,string,Javascript,Html,String,有没有一种简单的方法可以在JavaScript中提取html字符串并去掉html 如果您在浏览器中运行,那么最简单的方法就是 myString.replace(/<[^>]*>?/gm, ''); 注意:正如大家在评论中所指出的,如果您不控制HTML的源代码,那么最好避免这种情况。例如,不要在可能来自用户输入的任何内容上运行此操作。对于这些场景,您仍然可以让浏览器为您完成工作-。另一个公认不如nickf或Shog9优雅的解决方案是从标记开始递归遍历DOM并附加每个文本节点 v
myString.replace(/<[^>]*>?/gm, '');
注意:正如大家在评论中所指出的,如果您不控制HTML的源代码,那么最好避免这种情况。例如,不要在可能来自用户输入的任何内容上运行此操作。对于这些场景,您仍然可以让浏览器为您完成工作-。另一个公认不如nickf或Shog9优雅的解决方案是从标记开始递归遍历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;
}
将HTML转换为纯文本电子邮件,保持超链接a href完整
hypoxide发布的上述功能运行良好,但是我想要的东西基本上是转换在Web RichText编辑器中创建的HTML,例如FCKEditor,清除所有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, "");
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
然后在代码运行后,它看起来如下所示:-
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替换了和标记,以便保留某种视觉格式
更改链接格式,如BBC链接->http://www.bbc.co.uk 只需编辑$2链接->$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字符串中检索所有文本的 我修改为包括几种标记格式,删除内部的所有内容和标记,通过删除多个换行符和空格来格式化生成的HTML,并将一些HTML编码的代码转换为普通代码。经过一些测试,您似乎可以将大部分完整的web页面转换为简单文本,并保留页面标题和内容
在这个简单的例子中
<!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>
变成
这是我的头衔
此字符串包含我要删除的html代码
在这一行中,我们提到了英国广播公司的链接
现在,使用
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(/ /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 />
以下是sorta解决@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("");
但由于其他原因,这也不是一个完美的解决方案。使用jQuery,您只需使用
$('#elementID').text()
我自己创建了一个工作正则表达式:
str=str.replace(/(<\?[a-z]*(\s[^>]*)?\?(>|$)|<!\[[a-z]*\[|\]\]>|<!DOCTYPE[^>]*?(>|$)|<!--[\s\S]*?(-->|$)|<[a-z?!\/]([a-z0-9_:.])*(\s[^>]*)?(>|$))/gi, '');
作为jQuery方法的扩展,如果您的字符串可能不包含HTML,例如,如果您试图从表单字段中删除HTML
jQuery(html).text();
如果没有HTML,将返回空字符串
使用:
相反
更新:
正如评论中指出的,在某些情况下,此解决方案将执行html中包含的javascript。如果html的值可能受到攻击者的影响,请使用不同的解决方案。简单的两行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
对公认答案的改进
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请求中下载。我只需要去掉标记并用链接文本替换它们 这似乎很有效
htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '');
htmlContent= htmlContent.replace(/<\/a>/g, '');
在尝试了所有提到的答案后,大多数(如果不是所有的话)都有边缘案例,不能完全支持我的需求
我开始探索php是如何做到这一点的,并发现php.js lib在这里复制了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 : '';
});
}
帐户>内部属性和新创建的dom元素
用法:
clean_string = stripHTML("string with <html> in it")
演示:
top answer做可怕事情的演示:
也可以使用奇妙的纯JSHTML解析器。下面是一个工作演示:
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('');
输出将是这是一个简单的示例
请在此处查看它的实际操作:
这在节点和浏览器中都有效(如果您需要)
使用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等的链接和结构,那么你应该检查一下,你可以将其与任何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);
});
使用Jquery:
function stripTags() {
return $('<p></p>').html(textToEscape).text()
}
这应该可以在包含的任何Javascript环境节点上完成工作 常量文本=` *{颜色:红色} 提醒“你好” 这是一些文本 `; //删除样式标记和内容 text.replace/]*>.*/gm, //删除脚本标记和内容 .更换/]*>.*/gm, //删除所有打开、关闭和孤立HTML标记 .更换/]+>/gm, //删除前导空格并重复CR/LF .replace/[\r\n]++/gm;
很多人已经回答了这个问题,但我认为分享我编写的函数可能会很有用,该函数从字符串中剥离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>
输入元素:
文本状态表示元素值的单行纯文本编辑控件
更新:这是预期的工作
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;
}
我想分享一个编辑版本的 正如Mike Samuel在评论中指出的那样,该函数可以执行内联javascript代码。 但是Shog9说得对,让浏览器为你做吧 所以。。这里是我的编辑版本,使用: 下面是测试内联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, "");
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
此外,它不会请求类似解析的图像上的资源
strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")
这是一个正则表达式版本,它对格式错误的HTML更具弹性,如:
未闭合标签
一些文本
新行
一些
代码
使用jQuery剥离html的一种更安全的方法是,首先使用jQuery创建DOM,忽略任何脚本,然后让jQuery构建元素,然后仅检索文本 函数stripHtmlunsafe{ 返回$$.parseHTMLunsafe.text; } 可以安全地从以下内容中删除html: 以及其他的功绩
哎呀 要获得更简单的解决方案,请尝试此=> 来自CSS技巧: 常量原始字符串=` 嘿,那太糟糕了 `; 常量strippedString=originalString.replace/]+>/gi;
console.logstrippedString;哎呀。如果你想用你的字符串创建一个DOM树,那就用shog的方法吧!是的,我的解决方案在普通锤子更合适的地方使用大锤:-。我同意你和Shog9的解决方案更好,基本上在答案中也这么说了。我的回答中也没有反映html已经包含在字符串中,这使得我的回答对于原始问题基本上毫无用处-公平地说,这是有价值的——如果您绝对必须保留/全部/文本,那么这至少可以很好地捕获换行符、制表符、回车等。。。同样,nickf的解决方案也应该这样做,而且速度要快得多。。。呃,请记住,这种方法相当不一致,在某些浏览器中无法去除某些字符。例如,在Prototype.js中,我们使用这种方法来提高性能,但要解决一些不足之处——记住,您的空格将被弄乱。我曾经使用过这种方法,但后来出现了一些问题,因为某些产品代码包含双空格,在我从DIV中获取innerText后,这些双空格就变成了单空格。然后,这些产品代码在应用程序中不匹配。@Magnus Smith:是的,如果空格是一个问题,或者实际上,如果您需要不直接涉及您正在使用的特定HTMLDOM的文本,那么最好使用这里给出的其他解决方案之一。此方法的主要优点是1非常简单,2将以与正在运行的浏览器相同的方式可靠地处理标记、空白、实体、注释等。这通常对web客户端代码有用,但不一定适合与规则不同的其他系统交互。不要将此用于来自不受信任源的HTML。要了解原因,请尝试运行stripHTML。如果html包含imagesimg标记,则浏览器将请求这些图像。这不好。如果您是通过document.write进行注入,或者在通过innerHTML注入之前使用包含>的字符串进行连接,则不适用。@EversableDave,我同意>将保留在第二个字符串中。但这不是注射的危险。危险的发生是因为。@MikeSamuel我们决定这个答案了吗?这里的天真用户已经准备好复制粘贴了。我相信,如果假设HTML编写正确,这也会让人完全困惑,你仍然需要考虑gre
符号可能位于属性中引用文本的某个位置。另外,您至少要删除标记内部的所有文本。@AntonioMax,我已经回答了这个问题,但要回答您问题的实质,因为安全关键代码不应该被复制和粘贴。你应该下载一个库,并保持它的最新状态和补丁,这样你就可以防止最近发现的漏洞和浏览器的变化。我们总是在项目中使用jQuery,因为我们的项目总是有很多Javascript。因此,我们没有添加批量,我们利用了现有的API代码…您可以使用它,但OP可能不会。问题是关于Javascript而不是JQuery。对于像我这样需要做与OP相同的事情的人来说,这仍然是一个有用的答案,并且不介意像我这样使用JQuery,更不用说,如果他们考虑使用JQuery,它可能对OP有用。这个网站的目的是分享知识。请记住,无正当理由地批评有用的答案可能会产生寒蝉效应。@Dementic令人震惊的是,我发现有多个答案的线索是最有用的,因为通常第二个答案满足我的确切需要,而主要答案符合一般情况。如果字符串的某些部分没有包装在html标记中,则这将不起作用。e、 错误:请输入一个有效的电子邮件将返回唯一的错误:我喜欢这个解决方案,因为它有处理html特殊字符。。。但仍然远远不够。。。对我来说,最好的答案是解决所有这些问题。这可能就是jquery所做的。我认为//gi应该是//gi。请注意,要删除所有标记,您可以使用一个好的正则表达式来代替://这样,您只需要一个替换,而不是3个。另外,在我看来,除了实体的解码,你可以有一个正则表达式,类似这样://.Nice脚本。但是表格内容呢?你知道怎么会这样吗displayed@DanielGerson,编码html变得非常复杂,非常快,但是如果您关心安全性,就不要这样做。如果用户输入为:“alert42;”然后剥离的版本将是这样的:“alert42;”。因此,这是一个XSS漏洞。您应该使用[^>]更改[^],因为有效的标记不能包含或$.htmlhtml.text;这仍然执行可能很危险的代码jQuery'Text:';脚本>警报1&X003c/脚本>文本;这只适用于标签,需要调整才能成为一个广泛的功能。是的,加上锚定标签可以有许多其他属性,如title=…如果文本来自用户输入textarea或contenteditable小部件,在许多情况下都会失败…这是一个整洁的功能,并且有很好的文档记录。然而,当allowed==我认为这是OP要求的,这几乎是Byron在下面回答的Byron只错了[^>]时,它可以变得更快。如果您使用allowed参数,您就容易受到XSS:stripTags“
mytext
”,“”的攻击,返回mytext
,您应该引用源phpjs。如果使用允许的参数,则易受XSS:stripTags“mytext
”的攻击,“”返回mytext
,这是其中的一种方式,但不安全;在Chromium/Opera/Firefox Linux上没有运行任何脚本,那么为什么它不安全呢?很抱歉,我一定没有通过测试,我可能忘了在JSFIDLE上再次单击run。我认为新的参数是多余的?根据现在的说法,它是可选的,但并不总是如此。不起作用,在发布答案时,请始终提及您使用的浏览器。这是不准确的,在Chrome 61中不起作用。标记只是作为字符串呈现。您还需要处理属性值内的转义引号,例如,带有此文本的字符串应该被删除,但不是>示例。@pstanton您能给出一个语句的工作示例吗?*{font-family:comic sans;}一些Text@pstanton我已经修改了代码并添加了注释,抱歉,迟来的回答。请考虑阅读这些警告:值得一提的是,这个解决方案只在浏览器中工作。这不是条带标签,而是更像PHP HTMLPICTARCHARS。对我来说仍然很有用。请注意,这也会删除文本开头的空白。这似乎比@Shog9的回答快得多。此外,它不会尝试处理强制性警告: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;
}
function strip(html){
let doc = new DOMParser().parseFromString(html, 'text/html');
return doc.body.textContent || "";
}
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
var html = '<br>This <img alt="a>b" \r\n src="a_b.gif" />is > \nmy<>< > <a>"text"</a'
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
var StrippedString = OriginalString.replace(/(<([^>]+)>)/ig,"");