programing

HTML을 일반 텍스트로 변환하려면 어떻게 해야 합니까?

topblog 2023. 4. 23. 09:58
반응형

HTML을 일반 텍스트로 변환하려면 어떻게 해야 합니까?

테이블에 HTML 조각이 저장되어 있습니다.페이지 전체도 아니고 태그도 없고 기본적인 포맷만 가능합니다.

그 HTML을 특정 페이지(실제로 처음 30~50자만 표시하지만 쉬운 비트)에 서식 없이 텍스트로만 표시할 수 있도록 하고 싶습니다.

HTML 내의 "텍스트"를 스트레이트 텍스트로 문자열에 배치하려면 어떻게 해야 합니까?

그래서 이 코드 조각.

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

이하가 됩니다.

안녕 세계.밖에 아무도 없어요?

MIT 라이선스가 부여된HtmlAgilityPack의 샘플하나에는 HTML에서 일반 텍스트로 변환하는 메서드가 있습니다.

var plainText = HtmlUtilities.ConvertToPlainText(string html);

다음과 같은 HTML 문자열 제공

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

다음과 같은 간단한 텍스트 결과를 얻을 수 있습니다.

hello world!

Html Agility Pack을 사용할 수 없었기 때문에 두 번째로 좋은 솔루션을 작성했습니다.

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;
}

한다면, 태그스트립은 입니다.<script>태그 없이 텍스트를 표시하기만 하면 정규 표현으로 표시할 수 있습니다.

<[^>]*>

<script>태그 등의 경우 상태를 추적해야 하기 때문에 정규 표현보다 조금 더 강력한 것이 필요합니다.CFG(Context Free Grammar)입니다.'에서 오른쪽으로' 매칭으로할 수 왼쪽에서 오른쪽으로' 또는 욕심이 없는 매칭으로 이를 달성할 수 있을 것으로 생각됩니다.

정규 표현을 사용할 수 있다면 유용한 정보를 제공하는 웹 페이지가 많이 있습니다.

CFG의 보다 복잡한 동작이 필요한 경우 서드파티 툴을 사용할 것을 권장합니다.유감스럽게도 추천할 만한 툴은 없습니다.

HTTPUtility.HTMLEncode()는 HTML 태그를 문자열로 인코딩하는 것을 의미합니다.그것은 당신을 위한 모든 무거운 짐을 덜어줍니다.MSDN 매뉴얼:

HTTP 스트림에서 공백이나 구두점 등의 문자가 전달되면 수신측에서 잘못 해석될 수 있습니다.HTML 인코딩은 HTML에서 허용되지 않는 문자를 동등한 문자로 변환합니다.HTML 코 html html html html html html html 。를 들어,, 「」는 「」, 「」입니다.< ★★★★★★★★★★★★★★★★★」> 「하다」라고 .&lt; ★★★★★★★★★★★★★★★★★」&gt;HTTP の http http http 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();

HTML을 일반 텍스트로 변환하는 3단계 프로세스

먼저 HtmlAgilityPack용 Nuget 패키지를 설치해야 합니다.다음으로 이 클래스를 만듭니다.

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;
        }
    }
}

유다 히망고의 답변을 참고하여 위 클래스를 사용함

번째, '위 클래스의 오브젝트'를 '사용하다'를 합니다.ConvertHtml(HTMLContent)을 HTML이 ConvertToPlainText(string html);

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

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;
}

긴 인라인 공백이 무너지지 않는다는 제한이 있지만, 확실히 휴대성이 뛰어나 웹 브라우저와 같은 레이아웃을 존중합니다.

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;
}

가장 쉬운 방법은 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, "");
        }
}

그런 다음 프로그램의 'string' 변수에 대해 다음 확장 메서드를 사용합니다.

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

html 형식의 코멘트를 플레인 텍스트로 변환하여 크리스탈 리포트에 올바르게 표시되도록 하기 위해 이 확장 방법을 사용하고 있으며, 완벽하게 동작합니다!

내가 찾은 가장 간단한 방법:

HtmlFilter.ConvertToPlainText(html);

HtmlFilter 클래스는 Microsoft에 있습니다.Team Foundation.WorkItemTracking 입니다.Controls.dll

dll은 다음과 같은 폴더에 있습니다: %ProgramFiles%\공통 파일\Microsoft 공유\Team Foundation Server \140\

VS 2015에서 dll은 Microsoft에 대한 참조도 필요합니다.Team Foundation.WorkItemTracking 입니다.같은 폴더에 있는 Common.dll.

이름이 'ConvertToPlain'인 메서드가 없습니다.Text'는 HtmlAgilityPack에 포함되지만 다음과 같이 html 문자열을 CLEAR 문자열로 변환할 수 있습니다.

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

난 그게 좋아.하지만 'ConvertToPlain'이라는 이름의 메서드를 찾을 수 없습니다.'HtmlAgilityPack'의 텍스트.

같은 질문을 했습니다만, 제 html에는 다음과 같은 단순한 사전 알려진 레이아웃이 있었습니다.

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

그래서 결국 이렇게 간단한 코드를 사용하게 되었습니다.

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

출력:

abc
def

저도 비슷한 문제에 직면하여 최선의 해결책을 찾았습니다. 아래 코드는 저에게 딱 맞습니다.

  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 등의 이스케이프 문자는 정규식이 예상대로 작동하지 않게 되므로 먼저 삭제해야 합니다.

또한 결과 문자열을 텍스트 상자에 올바르게 표시하려면 텍스트 속성에 할당하는 대신 텍스트 상자를 분할하고 줄 속성을 설정해야 할 수도 있습니다.

this.txtResult.라인 = 스트립HTML(이것)txt 소스Text("\r")를 분할합니다.ToCharArray();

출처 : https://www.codeproject.com/Articles/11902/Convert-HTML-to-Plain-Text-2

2023년에 대한 답을 업데이트하십시오.답변은 기본적으로 항상 같습니다.

  1. 최신 Html Agility Pack 설치

  2. HtmlAgilityPack을 사용하는 HtmlUtilities라는 유틸리티 클래스를 만듭니다.

  3. 사용방법:var plainText = HtmlUtilities.ConvertToPlainText(email.HtmlCode);

위 링크에서 복사한HtmlUtilities 클래스는 다음과 같습니다.

using HtmlAgilityPack;
using System;
using System.IO;

namespace ReadSharp
{
public class HtmlUtilities
{
/// <summary>
/// Converts HTML to plain text / strips tags.
/// </summary>
/// <param name="html">The HTML.</param>
/// <returns></returns>
public static string ConvertToPlainText(string html)
{
  HtmlDocument doc = new HtmlDocument();
  doc.LoadHtml(html);

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


/// <summary>
/// Count the words.
/// The content has to be converted to plain text before (using ConvertToPlainText).
/// </summary>
/// <param name="plainText">The plain text.</param>
/// <returns></returns>
public static int CountWords(string plainText)
{
  return !String.IsNullOrEmpty(plainText) ? plainText.Split(' ', '\n').Length : 0;
}


public static string Cut(string text, int length)
{
  if (!String.IsNullOrEmpty(text) && text.Length > length)
  {
    text = text.Substring(0, length - 4) + " ...";
  }
  return text;
}


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


private static 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;
        case "br":
          outText.Write("\r\n");
          break;
      }

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

HTML 태그를 가진 데이터가 있고 다른 사람이 태그를 볼 수 있도록 표시하려면 HttpServerUtility를 사용합니다.Html Encode.

HTML 태그가 있는 데이터가 있고 사용자에게 렌더링된 태그를 표시하려면 텍스트를 그대로 표시합니다.텍스트가 웹 페이지 전체를 나타내는 경우 IFRAME을 사용합니다.

HTML 태그를 가진 데이터가 있고 태그를 제거하고 형식화되지 않은 텍스트만 표시하려면 정규 표현을 사용하십시오.

'html'이 무슨 뜻인지에 따라 다르죠가장 복잡한 경우는 완전한 웹 페이지입니다.텍스트 모드 웹 브라우저를 사용할 수 있기 때문에 이 방법이 가장 다루기 쉽습니다.텍스트 모드 브라우저를 포함한 웹 브라우저를 나열하는 Wikipedia 문서를 참조하십시오.링스는 아마도 가장 잘 알려져 있을 것입니다만, 다른 것 중 하나가 당신의 필요에 따라 더 좋을지도 모릅니다.

쓰지는 않았지만 사용:

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 };
    }
  }
}

답은 간단하다고 생각합니다.

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

줄 바꿈이나 HTML 태그를 사용하지 않고 특정 HTML 문서의 텍스트 약어에 대한 OP 질문에 대한 정확한 해결책을 찾으시는 분은 아래 솔루션을 참조하십시오.

제안된 모든 솔루션과 마찬가지로 아래 코드에는 몇 가지 전제 조건이 있습니다.

  • 스크립트 또는 스타일 태그는 스크립트의 일부로 스크립트 및 스타일 태그를 포함할 수 없습니다.
  • 주요 인라인 요소만 공백 없이 인라인됩니다.he<span>ll</span>o출력해야 한다hello. 인라인 태그 목록: https://www.w3schools.com/htmL/html_blocks.asp

위의 사항을 고려하여 컴파일된 정규 표현을 사용한 다음 문자열 확장자는 html 이스케이프 문자와 늘 입력 시 늘로 예상되는 플레인텍스트를 출력합니다.

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);
}

저의 솔루션은 다음과 같습니다.

public string StripHTML(string html)
{
    if (string.IsNullOrWhiteSpace(html)) return "";

    // could be stored in static variable
    var regex = new Regex("<[^>]+>|\\s{2}", 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:

public static string StripTags2(string html) { html을 반환합니다.치환("<", "<")치환(">", ">"); }

이것에 의해, 문자열내의 「<」와 「>」를 모두 이스케이프 합니다.이게 네가 원하는 거야?

언급URL : https://stackoverflow.com/questions/286813/how-do-you-convert-html-to-plain-text

반응형