30 ответов:
Если вы работаете в браузере, то самый простой способ-это просто браузер сделает это за вас...
function strip(html) { var tmp = document.createElement("DIV"); tmp.innerHTML = html; return tmp.textContent || tmp.innerText || ""; }Примечание: как люди отметили в комментариях, этого лучше избегать, если вы не контролируете источник HTML (например, не запускайте это ни на чем, что могло бы исходить из пользовательского ввода). Для этих сценариев, вы можете еще пусть браузер сделает работу за вас -см. ответ Сабы на использование теперь широко доступного DOMParser.
как расширение метода jQuery, если ваша строка может не содержать HTML (например, если вы пытаетесь удалить HTML из поля формы)
jQuery(html).text();вернет пустую строку, если нет html
использование:
.
jQuery('<p>' + html + '</p>').text();обновление: Как было указано в комментариях, в некоторых случаях это решение будет выполнять javascript, содержащийся в
htmlесли значениеhtmlможет быть под влиянием злоумышленника, используйте другое решение.
Я хотел бы поделиться отредактированную версию 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'>")
преобразование HTML в обычный текст по электронной почте, сохраняя гиперссылки (с href, в) интактных
функции выше написал hypoxide работает нормально, но я был после чего-то, что будет в принципе преобразовать HTML, созданные в веб-richtext с редактора (например FCKEditor) и убрать все HTML, но оставить все ссылки из-за того, что я хотел, как HTML и обычный текст, чтобы помочь создать правильные части к СТМП электронной почты (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, " (Link->) "); str=str.replace(/<(?:.|\s)*?>/g, "");the
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(строки типа char) так что какое-то визуальное Форматирование было сохранено.для изменения формата ссылки (например.
BBC (Link->http://www.bbc.co.uk)) просто редактировать(Link->), где- это URL / URI href и- это текст гиперссылки. С помощью ссылок непосредственно в теле обычного текста большинство почтовых клиентов 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+ безопасны. Опера Престо все еще уязвима. Также изображения, упомянутые в строках, не загружаются в Chromium и Firefox, сохраняя http-запросы.
Я изменил ответ 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-код, который я хочу удалить
в этой строке Би-би-си (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's inside of them returnText=returnText.replace(/<p.*>/gi, "\n"); returnText=returnText.replace(/<a.*href="(.*?)".*>(.*?)<\/a>/gi, " ()"); //-- 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 />
другим, по общему признанию, менее элегантным решением, чем 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; }
Если вы хотите сохранить ссылки и структуру контента (h1, h2 и т. д.), то вы должны проверить TextVersionJS вы можете использовать его с любым HTML, хотя он был создан для преобразования HTML электронной почты в обычный текст.
использование очень прост. Например в узле.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 делает это и наткнулся на php.JS lib, который реплицирует метод strip_tags здесь: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(''); }учетные записи > внутренние атрибуты и
<img onerror="javascript">во вновь созданных элементах dom.использование:
clean_string = stripHTML("string with <html> in it")демо:
https://jsfiddle.net/gaby_de_wilde/pqayphzd/
демо топ ответ делать ужасные вещи:
многие люди уже ответили на это, но я подумал, что было бы полезно поделиться функцией, которую я написал, что удаляет 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>
Я внес некоторые изменения в оригинальный скрипт Jibberboy2000 Надеюсь, что это будет полезно для кого-то
str = '**ANY HTML CONTENT HERE**'; str=str.replace(/<\s*br\/*>/gi, "\n"); str=str.replace(/<\s*a.*href="(.*?)".*>(.*?)<\/a>/gi, " (Link->) "); str=str.replace(/<\s*\/*.+?>/ig, "\n"); str=str.replace(/ {2,}/gi, " "); str=str.replace(/\n+\s*/gi, "\n\n");
вот версия, в которой 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("");но это не идеальное решение, как для других причины.
Я думаю, что самый простой способ-просто использовать регулярные выражения, как кто-то упоминал выше. Хотя нет никаких причин использовать их кучу. Попробуйте:
stringWithHTML = stringWithHTML.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");
ниже код позволяет сохранить некоторые 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(, ) { return allowed.indexOf('<' + .toLowerCase() + '>') > -1 ? : ''; }); }
также можно использовать фантастический 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
это работает как в узле, так и в браузере, если вы упаковываете веб-приложение с помощью такого инструмента, как webpack.
мне просто нужно вырезать
<a>теги и заменить их на текст по ссылке.Это, кажется, работает отлично.
htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, ''); htmlContent= htmlContent.replace(/<\/a>/g, '');
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");это регулярное выражение версии, которая более устойчива к искаженным HTML, как:
незакрытые теги
Some text <img"" внутри атрибутов тега
Some text <img alt="x > y">строки
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, "");
Я сам создал рабочее регулярное выражение:
str=str.replace(/(<\?[a-z]*(\s[^>]*)?\?(>|$)|<!\[[a-z]*\[|\]\]>|<!DOCTYPE[^>]*?(>|$)|<!--[\s\S]*?(-->|$)|<[a-z?!\/]([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строкаnullвы получаете"null"(вместо "). Исправлено:function strip(html) { if (html == null) return ""; var tmp = document.createElement("DIV"); tmp.innerHTML = html; return tmp.textContent || tmp.innerText || ""; }
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+)[^\]]*](.*?)\[\/]/g, ' '); // 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; }
вы можете безопасно удалить html-теги с помощью iframe sandbox атрибут.
идея здесь заключается в том, что вместо того, чтобы регулярное выражение нашей строки, мы воспользуемся родной парсер браузера, вводя текст в 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's context const sanboxContext = sandbox.contentWindow.document; return (untrustedString) => { if (typeof untrustedString !== "string") return ""; // Write the untrusted string in the iframe's 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));
(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);
для escape-символов также это будет работать с использованием сопоставления шаблонов:
myString.replace(/((<)|(<)(?:.|\n)*?(>)|(>))/gm, '');
Comments