Is there an easy way to take a string of html in JavaScript and strip out the html?
Is there an easy way to take a string of html in JavaScript and strip out the html?
If you're running in a browser, then the easiest way is just to let the browser do it for you...
function stripHtml(html)
{
let tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
Note: as folks have noted in the comments, this is best avoided if you don't control the source of the HTML (for example, don't run this on anything that could've come from user input). For those scenarios, you can still let the browser do the work for you - see Saba's answer on using the now widely-available DOMParser.
I would like to share an edited version of the Shog9's approved answer.
As Mike Samuel pointed with a comment, that function can execute inline javascript codes.
But Shog9 is right when saying "let the browser do it for you..."
so.. here my edited version, using DOMParser:
function strip(html){
let doc = new DOMParser().parseFromString(html, 'text/html');
return doc.body.textContent || "";
}
here the code to test the inline javascript:
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Also, it does not request resources on parse (like images)
strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")
The above function posted by hypoxide works fine, but I was after something that would basically convert HTML created in a Web RichText editor (for example FCKEditor) and clear out all HTML but leave all the Links due the fact that I wanted both the HTML and the plain text version to aid creating the correct parts to an STMP email (both HTML and plain text).
After a long time of searching Google myself and my collegues came up with this using the regex engine in 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, "");
the str variable starts out like this:
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>
and then after the code has run it looks like this:-
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
As you can see the all the HTML has been removed and the Link have been persevered with the hyperlinked text is still intact. Also I have replaced the <p> and <br> tags with \n (newline char) so that some sort of visual formatting has been retained.
To change the link format (eg. BBC (Link->http://www.bbc.co.uk) ) just edit the $2 (Link->$1), where $1 is the href URL/URI and the $2 is the hyperlinked text. With the links directly in body of the plain text most SMTP Mail Clients convert these so the user has the ability to click on them.
Hope you find this useful.
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
This is a regex version, which is more resilient to malformed HTML, like:
Unclosed tags
Some text <img
"<", ">" inside tag attributes
Some text <img alt="x > y">
Newlines
Some <a
href="http://google.com">
The code
var html = '<br>This <img alt="a>b" \r\n src="a_b.gif" />is > \nmy<>< > <a>"text"</a'
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
from CSS tricks:
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);
Another, admittedly less elegant solution than nickf's or Shog9's, would be to recursively walk the DOM starting at the <body> tag and append each text node.
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;
}
For easier solution, try this => https://css-tricks.com/snippets/javascript/strip-html-tags-in-javascript/
var StrippedString = OriginalString.replace(/(<([^>]+)>)/ig,"");
const htmlParser= new DOMParser().parseFromString("<h6>User<p>name</p></h6>" , 'text/html');
const textString= htmlParser.body.textContent;
console.log(textString)
I think the easiest way is to just use Regular Expressions as someone mentioned above. Although there's no reason to use a bunch of them. Try:
stringWithHTML = stringWithHTML.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");
A safer way to strip the html with jQuery is to first use jQuery.parseHTML to create a DOM, ignoring any scripts, before letting jQuery build an element and then retrieving only the text.
function stripHtml(unsafe) {
return $($.parseHTML(unsafe)).text();
}
Can safely strip html from:
<img src="unknown.gif" onerror="console.log('running injections');">
And other exploits.
nJoy!
If you don't want to create a DOM for this (perhaps you're not in a browser context) you could use the striptags npm package.
import striptags from 'striptags'; //ES6 <-- pick one
const striptags = require('striptags'); //ES5 <-- pick one
striptags('<p>An HTML string</p>');
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)
As others suggested, I recommend using DOMParser when possible.
However, if you happen to be working inside a Node/JS Lambda or otherwise DOMParser is not available, I came up with the regex below to match most of the scenarios mentioned in previous answers/comments. It doesn't match $gt; and $lt; as some others may have a concern about, but should capture pretty much any other scenario.
const dangerousText = '?';
const htmlTagRegex = /<\/?([a-zA-Z]\s?)*?([a-zA-Z]+?=\s?".*")*?([\s/]*?)>/gi;
const sanitizedText = dangerousText.replace(htmlTagRegex, '');
This might be easy to simplify, but it should work for most situations. Hope it helps someone.
(function($){
$.html2text = function(html) {
if($('#scratch_pad').length === 0) {
$('<div id="lh_scratch"></div>').appendTo('body');
}
return $('#scratch_pad').html(html).text();
};
})(jQuery);
Define this as a jquery plugin and use it like as follows:
$.html2text(htmlContent);
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]);
}
method 1:
function cleanHTML(str){
str.replace(/<(?<=<)(.*?)(?=>)>/g, '<$1>');
}
function uncleanHTML(str){
str.replace(/<(?<=<)(.*?)(?=>)>/g, '<$1>');
}
method 2:
function cleanHTML(str){
str.replace(/</g, '<').replace(/>/g, '>');
}
function uncleanHTML(str){
str.replace(/</g, '<').replace(/>/g, '>');
}
also, don't forget if the user happens to post a math comment (ex: 1 < 2), you don't want to strip the whole comment. The browser (only tested chrome) doesn't run unicode as html tags. if you replace all < with < everyware in the string, the unicode will display < as text without running any html. I recommend method 2. jquery also works well $('#element').text();
var STR='<Your HTML STRING>''
var HTMLParsedText="";
var resultSet = STR.split('>')
var resultSetLength =resultSet.length
var counter=0
while(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);
This package works really well for stripping HTML: https://www.npmjs.com/package/string-strip-html
It works in both the browser and on the server (e.g. Node.js).
function strip_html_tags(str)
{
if ((str===null) || (str===''))
return false;
else
str = str.toString();
return str.replace(/<[^>]*>/g, '');
}