web-dev-qa-db-ja.com

テキストのJavaScriptからHTMLを削除

JavaScriptでHTMLの文字列を取り出してHTMLを削除する簡単な方法はありますか

555
Bryan

ブラウザで実行している場合、最も簡単な方法は ブラウザに実行させてください...

function strip(html)
{
   var tmp = document.createElement("DIV");
   tmp.innerHTML = html;
   return tmp.textContent || tmp.innerText || "";
}

注:コメントで指摘されているように、HTMLのソースを制御しない場合は、これを避けるのが最善です(たとえば、ユーザー入力から生じた可能性のあるものでこれを実行しないでください)。これらのシナリオでは、stillブラウザーに作業を任せることができます- 現在広く利用可能なDOMParserの使用に関するSabaの回答を参照

693
Shog9
myString.replace(/<(?:.|\n)*?>/gm, '');
481
nickf

最も簡単な方法:

jQuery(html).text();

これは、HTMLの文字列からすべてのテキストを取得します。

230
Mark

Shog9 の承認済み回答 の編集版を共有したいと思います。


Mike Samuel がコメント付きで指摘したように、その関数はインライン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'>")
73
Sabaz

JQueryメソッドの拡張機能として、あなたの文字列がHTMLに統一されていない可能性がある場合(例えば、フォームフィールドからHTMLを削除しようとしている場合)

jQuery(html).text();

hTMLがない場合は空の文字列を返します

つかいます:

jQuery('<p>' + html + '</p>').text();

代わりに。

更新: コメントで指摘されているように、状況によっては、htmlの値が攻撃者によって影響を受ける可能性がある場合、このソリューションはhtml内に含まれるjavascriptを実行します。

52
user999305

HTMLをプレーンテキストの電子メールに変換してハイパーリンク(href)をそのままにする

Hypoxideによって投稿された上記の関数は問題なく動作しますが、私は基本的にWeb RichTextエディタ(例えば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, "");

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はhrefのURL/URI、$2はハイパーリンクテキストです。プレーンテキストの本文に直接リンクがあるので、ほとんどのSMTPメールクライアントはこれらを変換するので、ユーザーはそれらをクリックすることができます。

あなたがこれが役に立つことを願っています。

35
Jibberboy2000

受け入れられた答えへの改善。

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リクエストを保存しません。

31
Janghou

これはどんなJavascript環境(NodeJSを含む)でも動作するはずです。 text.replace(/<[^>]+>/g, '');

17
Karl.S

Jibberboy2000の答え を変更して、いくつかの<BR />タグフォーマットを含め、<SCRIPT>タグと<STYLE>タグ内のすべてを削除し、複数の改行とスペースを削除して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コードを持っています

この行にはリンク付き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'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 />
15
Elendurwen
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, "");
8
hegemon

もう1つの、nickfやShog9よりも明らかにエレガントではない解決策は、<body>タグから始まって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;
}
7
Bryan

リンクとコンテンツの構造(h1、h2など)を保持したい場合は、 TextVersionJS をチェックアウトする必要があります。プレーンテキスト.

使い方はとても簡単です。例えば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);
});
6
gyula.nemeth

ほとんどすべての答えを試してみたところ、全部ではなくEdgeケースがあり、私のニーズを完全にサポートすることはできませんでした。

私はphpがどのようにそれをするかを探り始め、ここにstrip_tagsメソッドを複製するphp.js libに出会いました: http://phpjs.org/functions/strip_tags/

4
Deminetix
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('');
}

新しく作成されたdom要素の> inside属性と<img onerror="javascript">のアカウント。

使用法:

clean_string = stripHTML("string with <html> in it")

デモ:

https://jsfiddle.net/gaby_de_wilde/pqayphzd/ /

ひどいことをしているトップ答えのデモ:

https://jsfiddle.net/gaby_de_wilde/6f0jymL6/1/ /

4
user40521

多くの人がすでにこれに答えていますが、私が書いた関数を共有することは役に立つかもしれないと思いました。それはかなり短いですし、私のためにうまく働いてきました。

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>
4
Harry Stevens

オリジナルのJibber 2000スクリプトにいくつかの変更を加えました。

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");
3
Jaxolotl

一番簡単な方法は、上で述べたように、正規表現を使うことです。それらの束を使用する理由はありませんが。試してください:

stringWithHTML = stringWithHTML.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");
3
Byron Carasco

ここでみかん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("");

それはどちらか他の理由のための完璧なソリューションではありません。

3

iframeサンドボックス属性 を使用して、HTMLタグを安全に削除できます。

ここでの考え方は、文字列を正規表現するのではなく、テキストを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 || "";
  };
})();

用法( demo ):

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));
2
Etienne Martin

私はちょうど<a>タグを取り除き、それらをリンクのテキストで置き換える必要がありました。

これはうまくいくようです。

htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '');
htmlContent= htmlContent.replace(/<\/a>/g, '');
2
FrigginGlorious

以下のコードでは、他のすべてのタグを削除しながら、いくつかの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 : '';
      });
}
2
aWebDeveloper

JQueryでは、次のようにして簡単に取得できます。

$('#elementID').text()
2
ianaz

素晴らしい htmlparser2 pure 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のようなツールを使用してWebアプリケーションをパックすると、これはノードとブラウザの両方で機能します。

2

hTMLを削除する単純な2行のjquery。

 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
1
Developer

Jqueryを使う:

function stripTags() {
    return $('<p></p>').html(textToEscape).text()
}
1
math2001

input要素 1行のテキストのみをサポート

テキスト状態は、要素の値に対する1行のプレーンテキスト編集コントロールを表します。

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;
}
1
Mike Datsko

私は自分で実用的な正規表現を作成しました:

str=str.replace(/(<\?[a-z]*(\s[^>]*)?\?(>|$)|<!\[[a-z]*\[|\]\]>|<!DOCTYPE[^>]*?(>|$)|<!--[\s\S]*?(-->|$)|<[a-z?!\/]([a-z0-9_:.])*(\s[^>]*)?(>|$))/gi, ''); 
1
MarekJ47

受け入れられた答えは大体うまくいきますが、IEではhtml文字列がnullであれば"null"が得られます( ''の代わりに)。一定:

function strip(html)
{
   if (html == null) return "";
   var tmp = document.createElement("DIV");
   tmp.innerHTML = html;
   return tmp.textContent || tmp.innerText || "";
}
1
basarat

エスケープ文字の場合も、これはパターンマッチングを使用して機能します。

myString.replace(/((&lt)|(<)(?:.|\n)*?(&gt)|(>))/gm, '');
    (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);
0
Shiv Shankar

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]);
}
0
sonichy
function strip_html_tags(str)
{
   if ((str===null) || (str===''))
       return false;
  else
   str = str.toString();
  return str.replace(/<[^>]*>/g, '');
}

HTMLをjQueryで取り除くより安全な方法は、最初に jQuery.parseHTML を使用してDOMを作成し、スクリプトを無視して、jQueryに要素を構築させてからテキストのみを取得させることです。

function stripHtml(unsafe) {
    return $($.parseHTML(unsafe)).text();
}

安全にhtmlを削除できます。

<img src="unknown.gif" onerror="console.log('running injections');">

そして他の悪用.

nジョイ!

0
nickl-