Есть ли простой способ взять строку html в JavaScript и вычеркнуть html?
Стриптиз HTML из текстового JavaScript
Ответ 1
Если вы работаете в браузере, то самый простой способ - позволить браузеру сделать это за вас...
function stripHtml(html)
{
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
Примечание: как отметили в комментариях люди, этого лучше избегать, если вы не контролируете источник HTML (например, не запускайте его на чем-либо, что могло бы быть получено из пользовательского ввода). Для этих сценариев вы все равно можете позволить браузеру сделать всю работу за вас - см. Ответ Saba об использовании теперь широко доступного DOMParser.
Ответ 2
myString.replace(/<[^>]*>?/gm, '');
Ответ 3
Простейший способ:
jQuery(html).text();
Это возвращает весь текст из строки html.
Ответ 4
Я хотел бы поделиться отредактированной версией одобренного Shog9 ответа.
Как указал Майк Самуэль с комментарием, эта функция может выполнять встроенные коды javascript.
Но Shog9 прав, говоря "пусть браузер сделает это за вас..."
так что.. здесь моя отредактированная версия, используя DOMParser:
function strip(html){
var 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'>")
Ответ 5
Как расширение метода jQuery, если ваша строка может не соответствовать HTML (например, если вы пытаетесь удалить HTML из поля формы)
jQuery(html).text();
возвращает пустую строку, если нет html
Использование:
jQuery('<p>' + html + '</p>').text();
вместо.
Update:
Как уже отмечалось в комментариях, в некоторых случаях это решение будет выполнять javascript, содержащийся в html
, если на значение html
может повлиять атакующий, используйте другое решение.
Ответ 6
Преобразование HTML для простого текстового письма с сохранением гиперссылок (href) intact
Вышеупомянутая функция, опубликованная hypoxy, отлично работает, но я был за чем-то, что в основном конвертировало бы HTML, созданный в редакторе Web RichText (например, FCKEditor), и очистил весь HTML, но оставил все ссылки из-за того, что мне хотелось, чтобы оба HTML и текстовую версию, чтобы помочь создать правильные части для электронной почты STMP (как HTML, так и обычного текста).
После долгого поиска Google я и мои коллеги придумали это с помощью механизма регулярных выражений в 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, "");
переменная 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 remove
Link Number 1 -> BBC (Link->http://www.bbc.co.uk) Link Number 1
Now back to normal text and stuff
Как вы можете видеть, все HTML были удалены, и ссылка была сохранена, а гиперссылнный текст по-прежнему неповрежден. Также я заменил теги <p>
и <br>
на \n
(newline char), чтобы сохранилось какое-то визуальное форматирование.
Чтобы изменить формат ссылки (например, BBC (Link->http://www.bbc.co.uk)
), просто отредактируйте $2 (Link->$1)
, где $1
- URL-адрес/URL-адрес href, а $2
- гиперссылнный текст. С помощью ссылок непосредственно в тексте обычного текста большинство почтовых клиентов SMTP конвертируют их, чтобы пользователь мог щелкнуть по ним.
Надеюсь, вы сочтете это полезным.
Ответ 7
Улучшение принятого ответа.
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-запросы.
Ответ 8
Это должно работать над любой средой Javascript (включая NodeJS).
text.replace(/<[^>]+>/g, '');
Ответ 9
Я изменил ответ Jibberboy2000, чтобы включить несколько форматов тегов <BR />
, удалить все внутри тегов <SCRIPT>
и <STYLE>
, отформатировать полученный HTML, удалив несколько строк перерывы и пробелы, а также преобразовать код HTML в нормальное состояние. После некоторого тестирования кажется, что вы можете конвертировать большую часть полных веб-страниц в простой текст, в котором сохранены заголовок и содержимое страницы.
В простом примере
<!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-код, который я хочу удалить
В этой строке упоминается 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 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 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 />
Ответ 10
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
Это версия регулярных выражений, которая более устойчива к искаженному HTML, например:
Незакрытые теги
Some text <img
"<", ">" внутри атрибутов тега
Some text <img alt="x > y">
Newlines
Some <a href="http://google.com">
Код
var html = '<br>This <img alt="a>b" \r\n src="a_b.gif" />is > \nmy<>< > <a>"text"</a'
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
Ответ 11
Другим, по общему признанию, менее элегантным решением, чем nickf или Shog9, было бы рекурсивно ходить DOM, начиная с <body> тег и добавьте каждый текст 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 value if it a text node
if (node.nodeType == 3) {
text += node.nodeValue;
}
// Recurse through the node children, if there are any
if (node.childNodes.length > 0) {
appendTextNodes(node);
}
}
// Return the final result
return text;
}
Ответ 12
Если вы хотите сохранить ссылки и структуру содержимого (h1, h2 и т.д.), вы должны проверить TextVersionJS Вы можете использовать его с любым 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);
});
Ответ 13
После того, как все ответы были упомянуты чаще всего, если не все из них имели краевые случаи и не могли полностью поддержать мои потребности.
Я начал изучать, как php делает это и наткнулся на php.js lib, который реплицирует метод strip_tags здесь: http://phpjs.org/functions/strip_tags/
Ответ 14
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('');
}
Учетные записи > внутренних атрибутов и <img onerror="javascript">
во вновь созданных элементах dom.
использование:
clean_string = stripHTML("string with <html> in it")
демо:
https://jsfiddle.net/gaby_de_wilde/pqayphzd/
демонстрация верхнего ответа, делающего ужасные вещи:
Ответ 15
Многие уже ответили на это, но я подумал, что было бы полезно разделить функцию, которую я написал, которая разбивает теги 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>
Ответ 16
Я думаю, что самый простой способ - просто использовать регулярные выражения, как упоминалось выше. Хотя нет причин использовать их. Попробуйте:
stringWithHTML = stringWithHTML.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");
Ответ 17
Я внес некоторые изменения в оригинальный Jibberboy2000 script Надеюсь, что это будет полезно для кого-то.
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");
Ответ 18
Здесь версия, которая сортирует адреса @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("");
но это не идеальное решение ни по другим причинам.
Ответ 19
Вы можете безопасно снимать теги html с помощью атрибута sandbox iframe.
Идея здесь заключается в том, что вместо того, чтобы пытаться повторно использовать нашу строку, мы используем собственный синтаксический анализатор браузера, textContent
текст в элемент DOM, а затем запрашивая textContent
/innerText
этого элемента.
Лучший подходящий элемент для ввода нашего текста - изолированный iframe, поэтому мы можем предотвратить произвольное выполнение кода (также известный как XSS).
Недостатком этого подхода является то, что он работает только в браузерах.
Вот что я придумал (не проверен на битву):
const stripHtmlTags = (() => {
const sandbox = document.createElement("iframe");
sandbox.sandbox = "allow-same-origin"; // <--- This is the key
sandbox.style.setProperty("display", "none", "important");
// Inject the sanbox in the current document
document.body.appendChild(sandbox);
// Get the sandbox context
const sanboxContext = sandbox.contentWindow.document;
return (untrustedString) => {
if (typeof untrustedString !== "string") return "";
// Write the untrusted string in the iframe body
sanboxContext.open();
sanboxContext.write(untrustedString);
sanboxContext.close();
// Get the string without html
return sanboxContext.body.textContent || sanboxContext.body.innerText || "";
};
})();
Использование (демо):
console.log(stripHtmlTags('<img onerror='alert("could run arbitrary JS here")' src='bogus'>XSS injection :)'));
console.log(stripHtmlTags('<script>alert("awdawd");</' + 'script>Script tag injection :)'));
console.log(stripHtmlTags('<strong>I am bold text</strong>'));
console.log(stripHtmlTags('<html>I'm a HTML tag</html>'));
console.log(stripHtmlTags('<body>I'm a body tag</body>'));
console.log(stripHtmlTags('<head>I'm a head tag</head>'));
console.log(stripHtmlTags(null));
Ответ 20
С помощью jQuery вы можете просто загрузить его с помощью
$('#elementID').text()
Ответ 21
Мне просто нужно было снять теги <a>
и заменить их текстом ссылки.
Это, кажется, отлично работает.
htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '');
htmlContent= htmlContent.replace(/<\/a>/g, '');
Ответ 22
Ниже код позволяет сохранять некоторые 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 : '';
});
}
Ответ 23
Также можно использовать фантастический htmlparser2 чистый JS HTML-парсер. Вот рабочая демонстрация:
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
Это работает как в node, так и в браузере, если вы упаковываете свое веб-приложение с помощью инструмента, такого как webpack.
Ответ 24
Я создал собственное регулярное выражение:
str=str.replace(/(<\?[a-z]*(\s[^>]*)?\?(>|$)|<!\[[a-z]*\[|\]\]>|<!DOCTYPE[^>]*?(>|$)|<!--[\s\S]*?(-->|$)|<[a-z?!\/]([a-z0-9_:.])*(\s[^>]*)?(>|$))/gi, '');
Ответ 25
простой 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
Ответ 26
Принятый ответ работает отлично, но в IE, если строка html
null
, вы получаете "null"
(вместо ''). Исправлено:
function strip(html)
{
if (html == null) return "";
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
Ответ 27
Использование JQuery:
function stripTags() {
return $('<p></p>').html(textToEscape).text()
}
Ответ 28
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;
}
Ответ 29
(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);
Ответ 30
Для escape-символов это будет работать с использованием сопоставления с образцом:
myString.replace(/((<)|(<)(?:.|\n)*?(>)|(>))/gm, '');