从文本JavaScript中剥离HTML

从文本JavaScript中剥离HTML,javascript,html,string,Javascript,Html,String,有没有一种简单的方法可以在JavaScript中提取html字符串并去掉html 如果您在浏览器中运行,那么最简单的方法就是 myString.replace(/<[^>]*>?/gm, ''); 注意:正如大家在评论中所指出的,如果您不控制HTML的源代码,那么最好避免这种情况。例如,不要在可能来自用户输入的任何内容上运行此操作。对于这些场景,您仍然可以让浏览器为您完成工作-。另一个公认不如nickf或Shog9优雅的解决方案是从标记开始递归遍历DOM并附加每个文本节点 v

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

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

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 &quot;normal text&quot; and stuff using &lt;html encoding&gt;                 
    </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(/&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><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&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

对公认答案的改进

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