首页 > 编程 > C# > 正文

C#实现将HTML转换成纯文本的方法

2019-10-29 21:40:44
字体:
来源:转载
供稿:网友
这篇文章主要介绍了C#实现将HTML转换成纯文本的方法,基于自定义类实现文本转换功能,具有一定参考借鉴价值,需要的朋友可以参考下
 

本文实例讲述了C#实现将HTML转换成纯文本的方法。分享给大家供大家参考。具体如下:

使用方法:

复制代码代码如下:
HtmlToText convert = new HtmlToText();
textBox2.Text = convert.Convert(textBox1.Text);

 

C#代码如下:
 

  1. /// <summary> 
  2. /// Converts HTML to plain text. 
  3. /// </summary> 
  4. class HtmlToText 
  5.   // Static data tables 
  6.   protected static Dictionary<string, string> _tags; 
  7.   protected static HashSet<string> _ignoreTags; 
  8.   // Instance variables 
  9.   protected TextBuilder _text; 
  10.   protected string _html; 
  11.   protected int _pos; 
  12.   // Static constructor (one time only) 
  13.   static HtmlToText() 
  14.   { 
  15.     _tags = new Dictionary<string, string>(); 
  16.     _tags.Add("address""/n"); 
  17.     _tags.Add("blockquote""/n"); 
  18.     _tags.Add("div""/n"); 
  19.     _tags.Add("dl""/n"); 
  20.     _tags.Add("fieldset""/n"); 
  21.     _tags.Add("form""/n"); 
  22.     _tags.Add("h1""/n"); 
  23.     _tags.Add("/h1""/n"); 
  24.     _tags.Add("h2""/n"); 
  25.     _tags.Add("/h2""/n"); 
  26.     _tags.Add("h3""/n"); 
  27.     _tags.Add("/h3""/n"); 
  28.     _tags.Add("h4""/n"); 
  29.     _tags.Add("/h4""/n"); 
  30.     _tags.Add("h5""/n"); 
  31.     _tags.Add("/h5""/n"); 
  32.     _tags.Add("h6""/n"); 
  33.     _tags.Add("/h6""/n"); 
  34.     _tags.Add("p""/n"); 
  35.     _tags.Add("/p""/n"); 
  36.     _tags.Add("table""/n"); 
  37.     _tags.Add("/table""/n"); 
  38.     _tags.Add("ul""/n"); 
  39.     _tags.Add("/ul""/n"); 
  40.     _tags.Add("ol""/n"); 
  41.     _tags.Add("/ol""/n"); 
  42.     _tags.Add("/li""/n"); 
  43.     _tags.Add("br""/n"); 
  44.     _tags.Add("/td""/t"); 
  45.     _tags.Add("/tr""/n"); 
  46.     _tags.Add("/pre""/n"); 
  47.     _ignoreTags = new HashSet<string>(); 
  48.     _ignoreTags.Add("script"); 
  49.     _ignoreTags.Add("noscript"); 
  50.     _ignoreTags.Add("style"); 
  51.     _ignoreTags.Add("object"); 
  52.   } 
  53.   /// <summary> 
  54.   /// Converts the given HTML to plain text and returns the result. 
  55.   /// </summary> 
  56.   /// <param name="html">HTML to be converted</param> 
  57.   /// <returns>Resulting plain text</returns> 
  58.   public string Convert(string html) 
  59.   { 
  60.     // Initialize state variables 
  61.     _text = new TextBuilder(); 
  62.     _html = html; 
  63.     _pos = 0; 
  64.     // Process input 
  65.     while (!EndOfText) 
  66.     { 
  67.       if (Peek() == '<'
  68.       { 
  69.         // HTML tag 
  70.         bool selfClosing; 
  71.         string tag = ParseTag(out selfClosing); 
  72.         // Handle special tag cases 
  73.         if (tag == "body"
  74.         { 
  75.           // Discard content before <body> 
  76.           _text.Clear(); 
  77.         } 
  78.         else if (tag == "/body"
  79.         { 
  80.           // Discard content after </body> 
  81.           _pos = _html.Length; 
  82.         } 
  83.         else if (tag == "pre"
  84.         { 
  85.           // Enter preformatted mode 
  86.           _text.Preformatted = true
  87.           EatWhitespaceToNextLine(); 
  88.         } 
  89.         else if (tag == "/pre"
  90.         { 
  91.           // Exit preformatted mode 
  92.           _text.Preformatted = false
  93.         } 
  94.         string value; 
  95.         if (_tags.TryGetValue(tag, out value)) 
  96.           _text.Write(value); 
  97.         if (_ignoreTags.Contains(tag)) 
  98.           EatInnerContent(tag); 
  99.       } 
  100.       else if (Char.IsWhiteSpace(Peek())) 
  101.       { 
  102.         // Whitespace (treat all as space) 
  103.         _text.Write(_text.Preformatted ? Peek() : ' '); 
  104.         MoveAhead(); 
  105.       } 
  106.       else 
  107.       { 
  108.         // Other text 
  109.         _text.Write(Peek()); 
  110.         MoveAhead(); 
  111.       } 
  112.     } 
  113.     // Return result 
  114.     return HttpUtility.HtmlDecode(_text.ToString()); 
  115.   } 
  116.   // Eats all characters that are part of the current tag 
  117.   // and returns information about that tag 
  118.   protected string ParseTag(out bool selfClosing) 
  119.   { 
  120.     string tag = String.Empty; 
  121.     selfClosing = false
  122.     if (Peek() == '<'
  123.     { 
  124.       MoveAhead(); 
  125.       // Parse tag name 
  126.       EatWhitespace(); 
  127.       int start = _pos; 
  128.       if (Peek() == '/'
  129.         MoveAhead(); 
  130.       while (!EndOfText && !Char.IsWhiteSpace(Peek()) && 
  131.         Peek() != '/' && Peek() != '>'
  132.         MoveAhead(); 
  133.       tag = _html.Substring(start, _pos - start).ToLower(); 
  134.       // Parse rest of tag 
  135.       while (!EndOfText && Peek() != '>'
  136.       { 
  137.         if (Peek() == '"' || Peek() == '/''
  138.           EatQuotedValue(); 
  139.         else 
  140.         { 
  141.           if (Peek() == '/'
  142.             selfClosing = true
  143.           MoveAhead(); 
  144.         } 
  145.       } 
  146.       MoveAhead(); 
  147.     } 
  148.     return tag; 
  149.   } 
  150.   // Consumes inner content from the current tag 
  151.   protected void EatInnerContent(string tag) 
  152.   { 
  153.     string endTag = "/" + tag; 
  154.     while (!EndOfText) 
  155.     { 
  156.       if (Peek() == '<'
  157.       { 
  158.         // Consume a tag 
  159.         bool selfClosing; 
  160.         if (ParseTag(out selfClosing) == endTag) 
  161.           return
  162.         // Use recursion to consume nested tags 
  163.         if (!selfClosing && !tag.StartsWith("/")) 
  164.           EatInnerContent(tag); 
  165.       } 
  166.       else MoveAhead(); 
  167.     } 
  168.   } 
  169.   // Returns true if the current position is at the end of 
  170.   // the string 
  171.   protected bool EndOfText 
  172.   { 
  173.     get { return (_pos >= _html.Length); } 
  174.   } 
  175.   // Safely returns the character at the current position 
  176.   protected char Peek() 
  177.   { 
  178.     return (_pos < _html.Length) ? _html[_pos] : (char)0; 
  179.   } 
  180.   // Safely advances to current position to the next character 
  181.   protected void MoveAhead() 
  182.   { 
  183.     _pos = Math.Min(_pos + 1, _html.Length); 
  184.   } 
  185.   // Moves the current position to the next non-whitespace 
  186.   // character. 
  187.   protected void EatWhitespace() 
  188.   { 
  189.     while (Char.IsWhiteSpace(Peek())) 
  190.       MoveAhead(); 
  191.   } 
  192.   // Moves the current position to the next non-whitespace 
  193.   // character or the start of the next line, whichever 
  194.   // comes first 
  195.   protected void EatWhitespaceToNextLine() 
  196.   { 
  197.     while (Char.IsWhiteSpace(Peek())) 
  198.     { 
  199.       char c = Peek(); 
  200.       MoveAhead(); 
  201.       if (c == '/n'
  202.         break
  203.     } 
  204.   } 
  205.   // Moves the current position past a quoted value 
  206.   protected void EatQuotedValue() 
  207.   { 
  208.     char c = Peek(); 
  209.     if (c == '"' || c == '/''
  210.     { 
  211.       // Opening quote 
  212.       MoveAhead(); 
  213.       // Find end of value 
  214.       int start = _pos; 
  215.       _pos = _html.IndexOfAny(new char[] { c, '/r''/n' }, _pos); 
  216.       if (_pos < 0) 
  217.         _pos = _html.Length; 
  218.       else 
  219.         MoveAhead();  // Closing quote 
  220.     } 
  221.   } 
  222.   /// <summary> 
  223.   /// A StringBuilder class that helps eliminate excess whitespace. 
  224.   /// </summary> 
  225.   protected class TextBuilder 
  226.   { 
  227.     private StringBuilder _text; 
  228.     private StringBuilder _currLine; 
  229.     private int _emptyLines; 
  230.     private bool _preformatted; 
  231.     // Construction 
  232.     public TextBuilder() 
  233.     { 
  234.       _text = new StringBuilder(); 
  235.       _currLine = new StringBuilder(); 
  236.       _emptyLines = 0; 
  237.       _preformatted = false
  238.     } 
  239.     /// <summary> 
  240.     /// Normally, extra whitespace characters are discarded. 
  241.     /// If this property is set to true, they are passed 
  242.     /// through unchanged. 
  243.     /// </summary> 
  244.     public bool Preformatted 
  245.     { 
  246.       get 
  247.       { 
  248.         return _preformatted; 
  249.       } 
  250.       set 
  251.       { 
  252.         if (value) 
  253.         { 
  254.           // Clear line buffer if changing to 
  255.           // preformatted mode 
  256.           if (_currLine.Length > 0) 
  257.             FlushCurrLine(); 
  258.           _emptyLines = 0; 
  259.         } 
  260.         _preformatted = value; 
  261.       } 
  262.     } 
  263.     /// <summary> 
  264.     /// Clears all current text. 
  265.     /// </summary> 
  266.     public void Clear() 
  267.     { 
  268.       _text.Length = 0; 
  269.       _currLine.Length = 0; 
  270.       _emptyLines = 0; 
  271.     } 
  272.     /// <summary> 
  273.     /// Writes the given string to the output buffer. 
  274.     /// </summary> 
  275.     /// <param name="s"></param> 
  276.     public void Write(string s) 
  277.     { 
  278.       foreach (char c in s) 
  279.         Write(c); 
  280.     } 
  281.     /// <summary> 
  282.     /// Writes the given character to the output buffer. 
  283.     /// </summary> 
  284.     /// <param name="c">Character to write</param> 
  285.     public void Write(char c) 
  286.     { 
  287.       if (_preformatted) 
  288.       { 
  289.         // Write preformatted character 
  290.         _text.Append(c); 
  291.       } 
  292.       else 
  293.       { 
  294.         if (c == '/r'
  295.         { 
  296.           // Ignore carriage returns. We'll process 
  297.           // '/n' if it comes next 
  298.         } 
  299.         else if (c == '/n'
  300.         { 
  301.           // Flush current line 
  302.           FlushCurrLine(); 
  303.         } 
  304.         else if (Char.IsWhiteSpace(c)) 
  305.         { 
  306.           // Write single space character 
  307.           int len = _currLine.Length; 
  308.           if (len == 0 || !Char.IsWhiteSpace(_currLine[len - 1])) 
  309.             _currLine.Append(' '); 
  310.         } 
  311.         else 
  312.         { 
  313.           // Add character to current line 
  314.           _currLine.Append(c); 
  315.         } 
  316.       } 
  317.     } 
  318.     // Appends the current line to output buffer 
  319.     protected void FlushCurrLine() 
  320.     { 
  321.       // Get current line 
  322.       string line = _currLine.ToString().Trim(); 
  323.       // Determine if line contains non-space characters 
  324.       string tmp = line.Replace(" ", String.Empty); 
  325.       if (tmp.Length == 0) 
  326.       { 
  327.         // An empty line 
  328.         _emptyLines++; 
  329.         if (_emptyLines < 2 && _text.Length > 0) 
  330.           _text.AppendLine(line); 
  331.       } 
  332.       else 
  333.       { 
  334.         // A non-empty line 
  335.         _emptyLines = 0; 
  336.         _text.AppendLine(line); 
  337.       } 
  338.       // Reset current line 
  339.       _currLine.Length = 0; 
  340.     } 
  341.     /// <summary> 
  342.     /// Returns the current output as a string. 
  343.     /// </summary> 
  344.     public override string ToString() 
  345.     { 
  346.       if (_currLine.Length > 0) 
  347.         FlushCurrLine(); 
  348.       return _text.ToString(); 
  349.     } 
  350.   } 
?

希望本文所述对大家的C#程序设计有所帮助。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表