HTMLをプレーンテキストに変換するにはどうすればよいですか?


98

Htmlのスニペットがテーブルに保存されています。ページ全体ではなく、タグなどではなく、基本的なフォーマットのみです。

特定のページで、Htmlをテキストとしてのみ表示し、書式設定を行わないようにします(実際には最初の30〜50文字だけですが、これは簡単なビットです)。

そのHTML内の「テキスト」をストレートテキストとして文字列に配置するにはどうすればよいですか?

このコードの一部です。

<b>Hello World.</b><br/><p><i>Is there anyone out there?</i><p>

になる:

こんにちは世界。誰かいますか?


SgmlReaderを使用することもできます。code.msdn.microsoft.com/SgmlReader
Leonardo Herrera

blackbeltcoder.com/Articles/strings/convert-html-to-textには、HTMLをプレーンテキストに変換するための非常にシンプルでわかりやすいコードがいくつかあります。
ジョナサンウッド

これは私が必要とするものに対する正しい答えでした-ありがとう!
Shaul Behr 2012年

W3Cからいくつかの良い提案があります:w3.org/Tools/html2things.html
Rich

4
質問を6か月後に行われた質問の複製としてマークするにはどうすればよいですか?少し後ろ向きのようです...
スチュアートヘルヴィグ2013年

回答:


27

タグの除去について話している場合、<script>タグのようなことを心配する必要がなければ、それは比較的単純です。あなたがする必要があるすべてがタグなしでテキストを表示することであるなら、あなたは正規表現でそれを達成することができます:

<[^>]*>

<script>タグなどについて心配する必要がある場合は、状態を追跡する必要があるため、正規表現よりも少し強力なものが必要になります。「Left To Right」または貪欲でないマッチングでそれを達成できるかもしれませんが。

正規表現を使用できる場合は、多くのWebページに役立つ情報があります。

CFGのより複雑な動作が必要な場合は、サードパーティのツールを使用することをお勧めしますが、残念ながら、推奨できる適切なツールがわかりません。


3
また、属性値、コメント、XMLのPI / CDATA、およびレガシーHTMLのさまざまな一般的な不正な形式についても考慮する必要があります。一般に、[X] [HT] MLは正規表現を使用した解析に適していません。
ボビンス2008年

11
これはそれを行うには恐ろしい方法です。正しい方法は、libでHTMLを解析し、ホワイトリストに登録されたコンテンツのみを出力するdomをトラバースすることです。
usr

2
@usr:あなたが参照している部分は、回答のCFG部分です。Regexは、迅速で汚れたタグの除去に使用できます。弱点はありますが、迅速で簡単です。より複雑な解析には、CFGベースのツールを使用します(用語では、DOMを生成するlib)。私はテストを実行していませんが、パフォーマンスを考慮する必要がある場合に備えて、DOM解析が正規表現のストリッピングよりも遅いことを期待しています。
vfilby '29年

1
@vfilby、最初に頭に浮かぶ攻撃は、「<div id = \」(c#文字列構文)の書き込みです。末尾の引用符と閉じ括弧が欠落していることに注意してください。これにより、ブラウザーが混乱し、タグ構造のバランスが崩れると思います。あなたはこの攻撃について思いますか?それが機能しないことを確信できますか?厄介です
usr

1
@vfilby、構文解析ライブラリが混乱しているかどうかは問題ではありません。あなたがする必要があるのは、そこからDOM(すべてのDOM)を取り、ホワイトリストに登録されたコンポーネントのみを出力することです。これは常に安全で、解析されたDOMがどのように見えるかは問題ではありません。また、「単純な」メソッドがタグの削除に失敗する複数の例を説明しました。
usr

95

フリーでオープンソースのHtmlAgilityPackがあり、そのサンプルの一つにする方法をプレーンテキストにHTMLから変換します。

var plainText = HtmlUtilities.ConvertToPlainText(string html);

次のようなHTML文字列をフィードします

<b>hello, <i>world!</i></b>

そして、次のようなプレーンテキストの結果が得られます。

hello world!

10
以前にHtmlAgilityPackを使用しましたが、ConvertToPlainTextへの参照が表示されません。どこにあるか教えてもらえますか?
horatio

8
:ホレイショ、それはHtmlAgilityPackに付属しているサンプルの1つに含まれているhtmlagilitypack.codeplex.com/sourcecontrol/changeset/view/...
ユダガブリエルHimango

5
実際、Agility Packにはこれのための組み込みの方法はありません。リンクしているのは、Agility Packを使用してノードツリーをトラバースし、タグを削除scriptしてstyle、他の要素の内部テキストを出力文字列に書き込む例です。実際の入力での多くのテストに合格したとは思えません。
ルー

3
正しく機能するように改造する必要があるサンプルへのリンクではなく、機能するコードを誰かが提供できますか?
Eric K

5
サンプルは、今ここで見つけることができます:github.com/ceee/ReadSharp/blob/master/ReadSharp/...
StuartQ

51

HtmlAgilityPackを使用できなかったので、自分のために2番目に優れたソリューションを作成しました

private static string HtmlToPlainText(string html)
{
    const string tagWhiteSpace = @"(>|$)(\W|\n|\r)+<";//matches one or more (white space or line breaks) between '>' and '<'
    const string stripFormatting = @"<[^>]*(>|$)";//match any character between '<' and '>', even when end tag is missing
    const string lineBreak = @"<(br|BR)\s{0,1}\/{0,1}>";//matches: <br>,<br/>,<br />,<BR>,<BR/>,<BR />
    var lineBreakRegex = new Regex(lineBreak, RegexOptions.Multiline);
    var stripFormattingRegex = new Regex(stripFormatting, RegexOptions.Multiline);
    var tagWhiteSpaceRegex = new Regex(tagWhiteSpace, RegexOptions.Multiline);

    var text = html;
    //Decode html specific characters
    text = System.Net.WebUtility.HtmlDecode(text); 
    //Remove tag whitespace/line breaks
    text = tagWhiteSpaceRegex.Replace(text, "><");
    //Replace <br /> with line breaks
    text = lineBreakRegex.Replace(text, Environment.NewLine);
    //Strip formatting
    text = stripFormattingRegex.Replace(text, string.Empty);

    return text;
}

2
&lt; blabla&gt; 解析されたので、テキストを移動しました= System.Net.WebUtility.HtmlDecode(text); メソッドの一番下
Luuk

1
これは素晴らしかったです。htmlがCMSから生成された可能性があるため、マルチスペースコンデンサーも追加しました。
Enkode

時々、htmlコードにコーダーの新しい行があります(コメントに新しい行が表示されないため、次のように[新しい行]で表示します:<br> I [新しい行]ミス[新しい行]あなた<br> >、つまり、「あなたがいなくて
寂しい

@ 123iamkingテキストを返す前にこれを使用できます。:text.Replace( "[改行]"、 "\ n");
Eslam Badawy

これを使用していて、文字列の先頭に「>」が残る場合があることに気付きました。正規表現<[^>] *>を適用する他のソリューションは正常に機能します。
エティエンヌシャーランド

20

HTTPUtility.HTMLEncode()HTMLタグのエンコードを文字列として処理するためのものです。それはあなたのためにすべての重い作業を処理します。MSDNドキュメントから:

ブランクや句読点などの文字がHTTPストリームで渡されると、受信側でそれらが誤って解釈される可能性があります。HTMLエンコーディングは、HTMLで許可されていない文字を同等の文字エンティティに変換します。HTMLデコードはエンコードを逆にします。テキストのブロックに埋め込まれた場合、例えば、文字<とは>、のように符号化される&lt;と、&gt;HTTP送信のため。

HTTPUtility.HTMLEncode()メソッド、ここで詳しく説明します

public static void HtmlEncode(
  string s,
  TextWriter output
)

使用法:

String TestString = "This is a <Test String>.";
StringWriter writer = new StringWriter();
Server.HtmlEncode(TestString, writer);
String EncodedString = writer.ToString();

ジョージは本当に良い回答でした。また、初めて質問したときの質の悪さも強調しました。ごめんなさい。
スチュアートヘルヴィヒ2008年

htmlアジリティパックは古く、html5をサポートしていません
abzarak

10

vfilbyの答えに追加するには、コード内でRegEx置換を実行するだけです。新しいクラスは必要ありません。私のような他の初心者がこの質問に失敗する場合に備えて。

using System.Text.RegularExpressions;

その後...

private string StripHtml(string source)
{
        string output;

        //get rid of HTML tags
        output = Regex.Replace(source, "<[^>]*>", string.Empty);

        //get rid of multiple blank lines
        output = Regex.Replace(output, @"^\s*$\n", string.Empty, RegexOptions.Multiline);

        return output;
}

19
良くない!これは、終了山かっこを省略して、スクリプトを含めるようにだますことができます。みんな、ブラックリストに載せないで。ブラックリストを使用して入力をサニタイズすることはできません。これは間違っています。
usr

7

HTMLをプレーンテキストに変換する3つのステッププロセス

まずあなたNugetパッケージのインストールが必要HtmlAgilityPack このクラスを作成します。第二に

public class HtmlToText
{
    public HtmlToText()
    {
    }

    public string Convert(string path)
    {
        HtmlDocument doc = new HtmlDocument();
        doc.Load(path);

        StringWriter sw = new StringWriter();
        ConvertTo(doc.DocumentNode, sw);
        sw.Flush();
        return sw.ToString();
    }

    public string ConvertHtml(string html)
    {
        HtmlDocument doc = new HtmlDocument();
        doc.LoadHtml(html);

        StringWriter sw = new StringWriter();
        ConvertTo(doc.DocumentNode, sw);
        sw.Flush();
        return sw.ToString();
    }

    private void ConvertContentTo(HtmlNode node, TextWriter outText)
    {
        foreach(HtmlNode subnode in node.ChildNodes)
        {
            ConvertTo(subnode, outText);
        }
    }

    public void ConvertTo(HtmlNode node, TextWriter outText)
    {
        string html;
        switch(node.NodeType)
        {
            case HtmlNodeType.Comment:
                // don't output comments
                break;

            case HtmlNodeType.Document:
                ConvertContentTo(node, outText);
                break;

            case HtmlNodeType.Text:
                // script and style must not be output
                string parentName = node.ParentNode.Name;
                if ((parentName == "script") || (parentName == "style"))
                    break;

                // get text
                html = ((HtmlTextNode)node).Text;

                // is it in fact a special closing node output as text?
                if (HtmlNode.IsOverlappedClosingElement(html))
                    break;

                // check the text is meaningful and not a bunch of whitespaces
                if (html.Trim().Length > 0)
                {
                    outText.Write(HtmlEntity.DeEntitize(html));
                }
                break;

            case HtmlNodeType.Element:
                switch(node.Name)
                {
                    case "p":
                        // treat paragraphs as crlf
                        outText.Write("\r\n");
                        break;
                }

                if (node.HasChildNodes)
                {
                    ConvertContentTo(node, outText);
                }
                break;
        }
    }
}

ユダ・ヒマンゴの答えに関連して上記のクラスを使用することによって

3番目に、上記のクラスのオブジェクトを作成し、ConvertHtml(HTMLContent)HTMLをプレーンテキストに変換するためのメソッドを使用する必要があります。ConvertToPlainText(string html);

HtmlToText htt=new HtmlToText();
var plainText = htt.ConvertHtml(HTMLContent);

HTMLのリンクの変換をスキップできますか?テキストに変換するときにリンクをhtmlに保つ必要がありますか?
coder771

6

長いインライン空白を折りたたまないという制限がありますが、確実に移植可能であり、webbrowserのようなレイアウトを尊重します。

static string HtmlToPlainText(string html) {
  string buf;
  string block = "address|article|aside|blockquote|canvas|dd|div|dl|dt|" +
    "fieldset|figcaption|figure|footer|form|h\\d|header|hr|li|main|nav|" +
    "noscript|ol|output|p|pre|section|table|tfoot|ul|video";

  string patNestedBlock = $"(\\s*?</?({block})[^>]*?>)+\\s*";
  buf = Regex.Replace(html, patNestedBlock, "\n", RegexOptions.IgnoreCase);

  // Replace br tag to newline.
  buf = Regex.Replace(buf, @"<(br)[^>]*>", "\n", RegexOptions.IgnoreCase);

  // (Optional) remove styles and scripts.
  buf = Regex.Replace(buf, @"<(script|style)[^>]*?>.*?</\1>", "", RegexOptions.Singleline);

  // Remove all tags.
  buf = Regex.Replace(buf, @"<[^>]*(>|$)", "", RegexOptions.Multiline);

  // Replace HTML entities.
  buf = WebUtility.HtmlDecode(buf);
  return buf;
}

4

HtmlAgilityPackに 'ConvertToPlainText'という名前のメソッドはありませんが、次のようにしてHTML文字列をCLEAR文字列に変換できます。

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlString);
var textString = doc.DocumentNode.InnerText;
Regex.Replace(textString , @"<(.|n)*?>", string.Empty).Replace("&nbsp", "");

それでうまくいきます。しかし、「HtmlAgilityPack」に「ConvertToPlainText」という名前のメソッドはありません。


3

私は最も簡単な方法は、(ユーザーRichardが提案したことに基づいて) 'string'拡張メソッドを作成することだと思います:

using System;
using System.Text.RegularExpressions;

public static class StringHelpers
{
    public static string StripHTML(this string HTMLText)
        {
            var reg = new Regex("<[^>]+>", RegexOptions.IgnoreCase);
            return reg.Replace(HTMLText, "");
        }
}

次に、プログラムの「文字列」変数にこの拡張メソッドを使用します。

var yourHtmlString = "<div class=\"someclass\"><h2>yourHtmlText</h2></span>";
var yourTextString = yourHtmlString.StripHTML();

この拡張メソッドを使用してhtml形式のコメントをプレーンテキストに変換します。これにより、Crystalレポートに正しく表示され、完全に機能します。


3

私が見つけた最も簡単な方法:

HtmlFilter.ConvertToPlainText(html);

HtmlFilterクラスはMicrosoft.TeamFoundation.WorkItemTracking.Controls.dllにあります

DLLは次のようなフォルダーにあります:%ProgramFiles%\ Common Files \ microsoft shared \ Team Foundation Server \ 14.0 \

VS 2015では、dllには、同じフォルダーにあるMicrosoft.TeamFoundation.WorkItemTracking.Common.dllへの参照も必要です。


スクリプトタグを処理し、太字のイタリックなどにフォーマットしますか?
Samra

htmlをプレーンテキストに変換するためのチーム基盤の依存関係の導入、非常に疑わしい...
ViRuSTriNiTy

2

HTMLタグのあるデータがあり、そのタグを表示できるように表示したい場合は、HttpServerUtility :: HtmlEncodeを使用します。

HTMLタグが含まれているデータがあり、レンダリングされたタグをユーザーに表示する場合は、テキストをそのまま表示します。テキストがWebページ全体を表す場合は、IFRAMEを使用します。

HTMLタグを含むデータがあり、タグを取り除いてフォーマットされていないテキストを表示したい場合は、正規表現を使用します。


phpにはstriptags()という関数があります。おそらく似たようなものがあります
markus

「正規表現を使う」NO!これはブラックリストになります。ホワイトリスト登録を行うのは安全です。たとえば、スタイル属性に「background:url( 'javascript:...');」を含めることができることを誰が覚えていますか?もちろん、そうではありません。そのため、ブラックリストは機能しません。
usr

2

私は同様の問題に直面し、最善の解決策を見つけました。以下のコードは私にとって完璧に機能します。

  private string ConvertHtml_Totext(string source)
    {
     try
      {
      string result;

    // Remove HTML Development formatting
    // Replace line breaks with space
    // because browsers inserts space
    result = source.Replace("\r", " ");
    // Replace line breaks with space
    // because browsers inserts space
    result = result.Replace("\n", " ");
    // Remove step-formatting
    result = result.Replace("\t", string.Empty);
    // Remove repeating spaces because browsers ignore them
    result = System.Text.RegularExpressions.Regex.Replace(result,
                                                          @"( )+", " ");

    // Remove the header (prepare first by clearing attributes)
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*head([^>])*>","<head>",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"(<( )*(/)( )*head( )*>)","</head>",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(<head>).*(</head>)",string.Empty,
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // remove all scripts (prepare first by clearing attributes)
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*script([^>])*>","<script>",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"(<( )*(/)( )*script( )*>)","</script>",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    //result = System.Text.RegularExpressions.Regex.Replace(result,
    //         @"(<script>)([^(<script>\.</script>)])*(</script>)",
    //         string.Empty,
    //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"(<script>).*(</script>)",string.Empty,
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // remove all styles (prepare first by clearing attributes)
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*style([^>])*>","<style>",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"(<( )*(/)( )*style( )*>)","</style>",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(<style>).*(</style>)",string.Empty,
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // insert tabs in spaces of <td> tags
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*td([^>])*>","\t",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // insert line breaks in places of <BR> and <LI> tags
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*br( )*>","\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*li( )*>","\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // insert line paragraphs (double line breaks) in place
    // if <P>, <DIV> and <TR> tags
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*div([^>])*>","\r\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*tr([^>])*>","\r\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*p([^>])*>","\r\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // Remove remaining tags like <a>, links, images,
    // comments etc - anything that's enclosed inside < >
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<[^>]*>",string.Empty,
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // replace special characters:
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @" "," ",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&bull;"," * ",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&lsaquo;","<",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&rsaquo;",">",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&trade;","(tm)",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&frasl;","/",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&lt;","<",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&gt;",">",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&copy;","(c)",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&reg;","(r)",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    // Remove all others. More can be added, see
    // http://hotwired.lycos.com/webmonkey/reference/special_characters/
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&(.{2,6});", string.Empty,
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // for testing
    //System.Text.RegularExpressions.Regex.Replace(result,
    //       this.txtRegex.Text,string.Empty,
    //       System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // make line breaking consistent
    result = result.Replace("\n", "\r");

    // Remove extra line breaks and tabs:
    // replace over 2 breaks with 2 and over 4 tabs with 4.
    // Prepare first to remove any whitespaces in between
    // the escaped characters and remove redundant tabs in between line breaks
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(\r)( )+(\r)","\r\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(\t)( )+(\t)","\t\t",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(\t)( )+(\r)","\t\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(\r)( )+(\t)","\r\t",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    // Remove redundant tabs
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(\r)(\t)+(\r)","\r\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    // Remove multiple tabs following a line break with just one tab
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(\r)(\t)+","\r\t",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    // Initial replacement target string for line breaks
    string breaks = "\r\r\r";
    // Initial replacement target string for tabs
    string tabs = "\t\t\t\t\t";
    for (int index=0; index<result.Length; index++)
    {
        result = result.Replace(breaks, "\r\r");
        result = result.Replace(tabs, "\t\t\t\t");
        breaks = breaks + "\r";
        tabs = tabs + "\t";
    }

    // That's it.
    return result;
}
catch
{
    MessageBox.Show("Error");
    return source;
}

}

\ nや\ rなどのエスケープ文字は、正規表現が期待どおりに機能しなくなるため、最初に削除する必要がありました。

さらに、結果の文字列をテキストボックスに正しく表示するには、テキストプロパティに割り当てる代わりに、分割してテキストボックスのLinesプロパティを設定する必要がある場合があります。

this.txtResult.Lines = StripHTML(this.txtSource.Text).Split( "\ r" .ToCharArray());

ソース:https : //www.codeproject.com/Articles/11902/Convert-HTML-to-Plain-Text-2


0

「html」の意味によって異なります。最も複雑なケースは、完全なWebページです。テキストモードのWebブラウザを使用できるため、これも最も扱いやすい方法です。テキストモードのブラウザーを含む、WebブラウザーをリストしているWikipediaの記事を参照してください。リンクスはおそらく最もよく知られていますが、他の1つはあなたのニーズに適しているかもしれません。


彼が言ったように「私はテーブルにHtmlのスニペットが保存されています。」
Mは

0

これが私の解決策です:

public string StripHTML(string html)
{
    var regex = new Regex("<[^>]+>", RegexOptions.IgnoreCase);
    return System.Web.HttpUtility.HtmlDecode((regex.Replace(html, "")));
}

例:

StripHTML("<p class='test' style='color:red;'>Here is my solution:</p>");
// output -> Here is my solution:

0

同じ質問がありましたが、私のhtmlには、次のような単純な既知のレイアウトがありました:

<DIV><P>abc</P><P>def</P></DIV>

だから私はそのような単純なコードを使用してしまいました:

string.Join (Environment.NewLine, XDocument.Parse (html).Root.Elements ().Select (el => el.Value))

どの出力:

abc
def

0

書きませんでしたが、使用:

using HtmlAgilityPack;
using System;
using System.IO;
using System.Text.RegularExpressions;

namespace foo {
  //small but important modification to class https://github.com/zzzprojects/html-agility-pack/blob/master/src/Samples/Html2Txt/HtmlConvert.cs
  public static class HtmlToText {

    public static string Convert(string path) {
      HtmlDocument doc = new HtmlDocument();
      doc.Load(path);
      return ConvertDoc(doc);
    }

    public static string ConvertHtml(string html) {
      HtmlDocument doc = new HtmlDocument();
      doc.LoadHtml(html);
      return ConvertDoc(doc);
    }

    public static string ConvertDoc(HtmlDocument doc) {
      using (StringWriter sw = new StringWriter()) {
        ConvertTo(doc.DocumentNode, sw);
        sw.Flush();
        return sw.ToString();
      }
    }

    internal static void ConvertContentTo(HtmlNode node, TextWriter outText, PreceedingDomTextInfo textInfo) {
      foreach (HtmlNode subnode in node.ChildNodes) {
        ConvertTo(subnode, outText, textInfo);
      }
    }
    public static void ConvertTo(HtmlNode node, TextWriter outText) {
      ConvertTo(node, outText, new PreceedingDomTextInfo(false));
    }
    internal static void ConvertTo(HtmlNode node, TextWriter outText, PreceedingDomTextInfo textInfo) {
      string html;
      switch (node.NodeType) {
        case HtmlNodeType.Comment:
          // don't output comments
          break;
        case HtmlNodeType.Document:
          ConvertContentTo(node, outText, textInfo);
          break;
        case HtmlNodeType.Text:
          // script and style must not be output
          string parentName = node.ParentNode.Name;
          if ((parentName == "script") || (parentName == "style")) {
            break;
          }
          // get text
          html = ((HtmlTextNode)node).Text;
          // is it in fact a special closing node output as text?
          if (HtmlNode.IsOverlappedClosingElement(html)) {
            break;
          }
          // check the text is meaningful and not a bunch of whitespaces
          if (html.Length == 0) {
            break;
          }
          if (!textInfo.WritePrecedingWhiteSpace || textInfo.LastCharWasSpace) {
            html = html.TrimStart();
            if (html.Length == 0) { break; }
            textInfo.IsFirstTextOfDocWritten.Value = textInfo.WritePrecedingWhiteSpace = true;
          }
          outText.Write(HtmlEntity.DeEntitize(Regex.Replace(html.TrimEnd(), @"\s{2,}", " ")));
          if (textInfo.LastCharWasSpace = char.IsWhiteSpace(html[html.Length - 1])) {
            outText.Write(' ');
          }
          break;
        case HtmlNodeType.Element:
          string endElementString = null;
          bool isInline;
          bool skip = false;
          int listIndex = 0;
          switch (node.Name) {
            case "nav":
              skip = true;
              isInline = false;
              break;
            case "body":
            case "section":
            case "article":
            case "aside":
            case "h1":
            case "h2":
            case "header":
            case "footer":
            case "address":
            case "main":
            case "div":
            case "p": // stylistic - adjust as you tend to use
              if (textInfo.IsFirstTextOfDocWritten) {
                outText.Write("\r\n");
              }
              endElementString = "\r\n";
              isInline = false;
              break;
            case "br":
              outText.Write("\r\n");
              skip = true;
              textInfo.WritePrecedingWhiteSpace = false;
              isInline = true;
              break;
            case "a":
              if (node.Attributes.Contains("href")) {
                string href = node.Attributes["href"].Value.Trim();
                if (node.InnerText.IndexOf(href, StringComparison.InvariantCultureIgnoreCase) == -1) {
                  endElementString = "<" + href + ">";
                }
              }
              isInline = true;
              break;
            case "li":
              if (textInfo.ListIndex > 0) {
                outText.Write("\r\n{0}.\t", textInfo.ListIndex++);
              } else {
                outText.Write("\r\n*\t"); //using '*' as bullet char, with tab after, but whatever you want eg "\t->", if utf-8 0x2022
              }
              isInline = false;
              break;
            case "ol":
              listIndex = 1;
              goto case "ul";
            case "ul": //not handling nested lists any differently at this stage - that is getting close to rendering problems
              endElementString = "\r\n";
              isInline = false;
              break;
            case "img": //inline-block in reality
              if (node.Attributes.Contains("alt")) {
                outText.Write('[' + node.Attributes["alt"].Value);
                endElementString = "]";
              }
              if (node.Attributes.Contains("src")) {
                outText.Write('<' + node.Attributes["src"].Value + '>');
              }
              isInline = true;
              break;
            default:
              isInline = true;
              break;
          }
          if (!skip && node.HasChildNodes) {
            ConvertContentTo(node, outText, isInline ? textInfo : new PreceedingDomTextInfo(textInfo.IsFirstTextOfDocWritten) { ListIndex = listIndex });
          }
          if (endElementString != null) {
            outText.Write(endElementString);
          }
          break;
      }
    }
  }
  internal class PreceedingDomTextInfo {
    public PreceedingDomTextInfo(BoolWrapper isFirstTextOfDocWritten) {
      IsFirstTextOfDocWritten = isFirstTextOfDocWritten;
    }
    public bool WritePrecedingWhiteSpace { get; set; }
    public bool LastCharWasSpace { get; set; }
    public readonly BoolWrapper IsFirstTextOfDocWritten;
    public int ListIndex { get; set; }
  }
  internal class BoolWrapper {
    public BoolWrapper() { }
    public bool Value { get; set; }
    public static implicit operator bool(BoolWrapper boolWrapper) {
      return boolWrapper.Value;
    }
    public static implicit operator BoolWrapper(bool boolWrapper) {
      return new BoolWrapper { Value = boolWrapper };
    }
  }
}

0

私はそれが簡単な答えを持っていると思います:

public string RemoveHTMLTags(string HTMLCode)
{
    string str=System.Text.RegularExpressions.Regex.Replace(HTMLCode, "<[^>]*>", "");
    return str;
}

0

改行やHTMLタグを使用せずに、特定のHTMLドキュメントをテキストで略記するOPの質問に対する正確な解決策を探している人は、以下の解決策を見つけてください。

すべての提案されたソリューションと同様に、以下のコードにはいくつかの仮定があります。

  • スクリプトまたはスタイルタグには、スクリプトの一部としてスクリプトおよびスタイルタグを含めないでください。
  • 主要なインライン要素のみがスペースなしでインライン化されhe<span>ll</span>oますhello。つまり、が出力されます。インラインタグのリスト:https : //www.w3schools.com/htmL/html_blocks.asp

上記を考慮して、コンパイルされた正規表現を含む次の文字列拡張は、HTMLエスケープ文字およびnull入力のnullに関して予期されるプレーンテキストを出力します。

public static class StringExtensions
{
    public static string ConvertToPlain(this string html)
    {
        if (html == null)
        {
            return html;
        }

        html = scriptRegex.Replace(html, string.Empty);
        html = inlineTagRegex.Replace(html, string.Empty);
        html = tagRegex.Replace(html, " ");
        html = HttpUtility.HtmlDecode(html);
        html = multiWhitespaceRegex.Replace(html, " ");

        return html.Trim();
    }

    private static readonly Regex inlineTagRegex = new Regex("<\\/?(a|span|sub|sup|b|i|strong|small|big|em|label|q)[^>]*>", RegexOptions.Compiled | RegexOptions.Singleline);
    private static readonly Regex scriptRegex = new Regex("<(script|style)[^>]*?>.*?</\\1>", RegexOptions.Compiled | RegexOptions.Singleline);
    private static readonly Regex tagRegex = new Regex("<[^>]+>", RegexOptions.Compiled | RegexOptions.Singleline);
    private static readonly Regex multiWhitespaceRegex = new Regex("\\s+", RegexOptions.Compiled | RegexOptions.Singleline);
}

-4

public static string StripTags2(string html){return html.Replace( "<"、 "<")。Replace( ">"、 ">"); }

これにより、文字列内のすべての「<」と「>」をエスケープします。これは、あなたの望むことですか?


...ああ。さて、答えは(あいまいな質問の解釈とともに)完全に変更されました。代わりにエンコーディング。;-)
ボビンス、2008年

2
ホイールを再発明することは良い考えではないと思います。特に、ホイールが正方形の場合は。代わりにHTMLEncodeを使用してください。
Kramii 2008年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.