[c#] Html을 일반 텍스트로 어떻게 변환합니까?

테이블에 저장된 Html 조각이 있습니다. 전체 페이지가 아니라 태그 등이 아니라 기본 서식입니다.

주어진 페이지에서 해당 Html을 텍스트로만 표시하고 서식은 지정하지 않고 싶습니다 (실제로는 처음 30-50 자이지만 쉬운 부분입니다).

해당 Html 내의 “텍스트”를 직선 텍스트로 문자열에 배치하는 방법은 무엇입니까?

그래서이 코드 조각.

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

된다 :

안녕하세요. 거기 누구 있어요?



답변

태그 제거에 대해 이야기하는 경우 <script>태그 와 같은 것에 대해 걱정할 필요가 없으면 비교적 간단 합니다. 태그없이 텍스트를 표시하기 만하면 정규식으로 수행 할 수 있습니다.

<[^>]*>

<script>태그 등에 대해 걱정할 필요가있는 경우 상태를 추적해야하므로 CFG (Context Free Grammar)와 같은 것이므로 정규 표현식보다 더 강력한 것이 필요합니다. ‘왼쪽에서 오른쪽으로’또는 탐욕스럽지 않은 일치를 통해 수행 할 수는 있지만.

정규식을 사용할 수 있다면 좋은 정보가있는 많은 웹 페이지가 있습니다.

CFG의 더 복잡한 동작이 필요한 경우 타사 도구를 사용하는 것이 좋지만, 안타깝게도 권장 할만한 도구가 없습니다.


답변

무료 오픈 소스 HtmlAgilityPack 에는 샘플 중 하나에 HTML에서 일반 텍스트로 변환하는 메서드가 있습니다.

var plainText = HtmlUtilities.ConvertToPlainText(string html);

다음과 같은 HTML 문자열을 피드

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

그리고 다음과 같은 일반 텍스트 결과를 얻을 수 있습니다.

hello world!


답변

HtmlAgilityPack을 사용할 수 없어서 두 번째로 좋은 솔루션을 작성했습니다.

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


답변

HTTPUtility.HTMLEncode()HTML 태그를 문자열로 인코딩하는 것을 의미합니다. 그것은 당신을 위해 모든 무거운 짐을 처리합니다. 로부터 MSDN 문서 :

공백 및 구두점과 같은 문자가 HTTP 스트림에 전달되면 수신 측에서 잘못 해석 될 수 있습니다. HTML 인코딩은 HTML에서 허용되지 않는 문자를 해당 문자 엔티티로 변환합니다. HTML 디코딩은 인코딩을 반대로합니다. 예를 들어 텍스트 블록에 포함 된 경우 <및 문자 는 HTTP 전송을 위해 및 >로 인코딩됩니다 .&lt;&gt;

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


답변

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


답변

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


답변

긴 인라인 공백을 축소하지 않는 제한이 있지만 확실히 이식 가능하며 웹 브라우저와 같은 레이아웃을 존중합니다.

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