1. //1、HTML直接转文本
  2. //使用方法
  3. HtmlToText convert = new HtmlToText();
  4. textBox2.Text = convert.Convert(textBox1.Text);
  5. //代码
  6. /// <summary>
  7. /// Converts HTML to plain text.
  8. /// </summary>
  9. class HtmlToText
  10. {
  11. // Static data tables
  12. protected static Dictionary<string, string> _tags;
  13. protected static HashSet<string> _ignoreTags;
  14. // Instance variables
  15. protected TextBuilder _text;
  16. protected string _html;
  17. protected int _pos;
  18. // Static constructor (one time only)
  19. static HtmlToText()
  20. {
  21. _tags = new Dictionary<string, string>();
  22. _tags.Add("address", "\n");
  23. _tags.Add("blockquote", "\n");
  24. _tags.Add("div", "\n");
  25. _tags.Add("dl", "\n");
  26. _tags.Add("fieldset", "\n");
  27. _tags.Add("form", "\n");
  28. _tags.Add("h1", "\n");
  29. _tags.Add("/h1", "\n");
  30. _tags.Add("h2", "\n");
  31. _tags.Add("/h2", "\n");
  32. _tags.Add("h3", "\n");
  33. _tags.Add("/h3", "\n");
  34. _tags.Add("h4", "\n");
  35. _tags.Add("/h4", "\n");
  36. _tags.Add("h5", "\n");
  37. _tags.Add("/h5", "\n");
  38. _tags.Add("h6", "\n");
  39. _tags.Add("/h6", "\n");
  40. _tags.Add("p", "\n");
  41. _tags.Add("/p", "\n");
  42. _tags.Add("table", "\n");
  43. _tags.Add("/table", "\n");
  44. _tags.Add("ul", "\n");
  45. _tags.Add("/ul", "\n");
  46. _tags.Add("ol", "\n");
  47. _tags.Add("/ol", "\n");
  48. _tags.Add("/li", "\n");
  49. _tags.Add("br", "\n");
  50. _tags.Add("/td", "\t");
  51. _tags.Add("/tr", "\n");
  52. _tags.Add("/pre", "\n");
  53. _ignoreTags = new HashSet<string>();
  54. _ignoreTags.Add("script");
  55. _ignoreTags.Add("noscript");
  56. _ignoreTags.Add("style");
  57. _ignoreTags.Add("object");
  58. }
  59. /// <summary>
  60. /// Converts the given HTML to plain text and returns the result.
  61. /// </summary>
  62. /// <param name="html">HTML to be converted</param>
  63. /// <returns>Resulting plain text</returns>
  64. public string Convert(string html)
  65. {
  66. // Initialize state variables
  67. _text = new TextBuilder();
  68. _html = html;
  69. _pos = 0;
  70. // Process input
  71. while (!EndOfText)
  72. {
  73. if (Peek() == '<')
  74. {
  75. // HTML tag
  76. bool selfClosing;
  77. string tag = ParseTag(out selfClosing);
  78. // Handle special tag cases
  79. if (tag == "body")
  80. {
  81. // Discard content before <body>
  82. _text.Clear();
  83. }
  84. else if (tag == "/body")
  85. {
  86. // Discard content after </body>
  87. _pos = _html.Length;
  88. }
  89. else if (tag == "pre")
  90. {
  91. // Enter preformatted mode
  92. _text.Preformatted = true;
  93. EatWhitespaceToNextLine();
  94. }
  95. else if (tag == "/pre")
  96. {
  97. // Exit preformatted mode
  98. _text.Preformatted = false;
  99. }
  100. string value;
  101. if (_tags.TryGetValue(tag, out value))
  102. _text.Write(value);
  103. if (_ignoreTags.Contains(tag))
  104. EatInnerContent(tag);
  105. }
  106. else if (Char.IsWhiteSpace(Peek()))
  107. {
  108. // Whitespace (treat all as space)
  109. _text.Write(_text.Preformatted ? Peek() : ' ');
  110. MoveAhead();
  111. }
  112. else
  113. {
  114. // Other text
  115. _text.Write(Peek());
  116. MoveAhead();
  117. }
  118. }
  119. // Return result
  120. return HttpUtility.HtmlDecode(_text.ToString());
  121. }
  122. // Eats all characters that are part of the current tag
  123. // and returns information about that tag
  124. protected string ParseTag(out bool selfClosing)
  125. {
  126. string tag = String.Empty;
  127. selfClosing = false;
  128. if (Peek() == '<')
  129. {
  130. MoveAhead();
  131. // Parse tag name
  132. EatWhitespace();
  133. int start = _pos;
  134. if (Peek() == '/')
  135. MoveAhead();
  136. while (!EndOfText && !Char.IsWhiteSpace(Peek()) &&
  137. Peek() != '/' && Peek() != '>')
  138. MoveAhead();
  139. tag = _html.Substring(start, _pos - start).ToLower();
  140. // Parse rest of tag
  141. while (!EndOfText && Peek() != '>')
  142. {
  143. if (Peek() == '"' || Peek() == '\'')
  144. EatQuotedValue();
  145. else
  146. {
  147. if (Peek() == '/')
  148. selfClosing = true;
  149. MoveAhead();
  150. }
  151. }
  152. MoveAhead();
  153. }
  154. return tag;
  155. }
  156. // Consumes inner content from the current tag
  157. protected void EatInnerContent(string tag)
  158. {
  159. string endTag = "/" + tag;
  160. while (!EndOfText)
  161. {
  162. if (Peek() == '<')
  163. {
  164. // Consume a tag
  165. bool selfClosing;
  166. if (ParseTag(out selfClosing) == endTag)
  167. return;
  168. // Use recursion to consume nested tags
  169. if (!selfClosing && !tag.StartsWith("/"))
  170. EatInnerContent(tag);
  171. }
  172. else MoveAhead();
  173. }
  174. }
  175. // Returns true if the current position is at the end of
  176. // the string
  177. protected bool EndOfText
  178. {
  179. get { return (_pos >= _html.Length); }
  180. }
  181. // Safely returns the character at the current position
  182. protected char Peek()
  183. {
  184. return (_pos < _html.Length) ? _html[_pos] : (char)0;
  185. }
  186. // Safely advances to current position to the next character
  187. protected void MoveAhead()
  188. {
  189. _pos = Math.Min(_pos + 1, _html.Length);
  190. }
  191. // Moves the current position to the next non-whitespace
  192. // character.
  193. protected void EatWhitespace()
  194. {
  195. while (Char.IsWhiteSpace(Peek()))
  196. MoveAhead();
  197. }
  198. // Moves the current position to the next non-whitespace
  199. // character or the start of the next line, whichever
  200. // comes first
  201. protected void EatWhitespaceToNextLine()
  202. {
  203. while (Char.IsWhiteSpace(Peek()))
  204. {
  205. char c = Peek();
  206. MoveAhead();
  207. if (c == '\n')
  208. break;
  209. }
  210. }
  211. // Moves the current position past a quoted value
  212. protected void EatQuotedValue()
  213. {
  214. char c = Peek();
  215. if (c == '"' || c == '\'')
  216. {
  217. // Opening quote
  218. MoveAhead();
  219. // Find end of value
  220. int start = _pos;
  221. _pos = _html.IndexOfAny(new char[] { c, '\r', '\n' }, _pos);
  222. if (_pos < 0)
  223. _pos = _html.Length;
  224. else
  225. MoveAhead();    // Closing quote
  226. }
  227. }
  228. /// <summary>
  229. /// A StringBuilder class that helps eliminate excess whitespace.
  230. /// </summary>
  231. protected class TextBuilder
  232. {
  233. private StringBuilder _text;
  234. private StringBuilder _currLine;
  235. private int _emptyLines;
  236. private bool _preformatted;
  237. // Construction
  238. public TextBuilder()
  239. {
  240. _text = new StringBuilder();
  241. _currLine = new StringBuilder();
  242. _emptyLines = 0;
  243. _preformatted = false;
  244. }
  245. /// <summary>
  246. /// Normally, extra whitespace characters are discarded.
  247. /// If this property is set to true, they are passed
  248. /// through unchanged.
  249. /// </summary>
  250. public bool Preformatted
  251. {
  252. get
  253. {
  254. return _preformatted;
  255. }
  256. set
  257. {
  258. if (value)
  259. {
  260. // Clear line buffer if changing to
  261. // preformatted mode
  262. if (_currLine.Length > 0)
  263. FlushCurrLine();
  264. _emptyLines = 0;
  265. }
  266. _preformatted = value;
  267. }
  268. }
  269. /// <summary>
  270. /// Clears all current text.
  271. /// </summary>
  272. public void Clear()
  273. {
  274. _text.Length = 0;
  275. _currLine.Length = 0;
  276. _emptyLines = 0;
  277. }
  278. /// <summary>
  279. /// Writes the given string to the output buffer.
  280. /// </summary>
  281. /// <param name="s"></param>
  282. public void Write(string s)
  283. {
  284. foreach (char c in s)
  285. Write(c);
  286. }
  287. /// <summary>
  288. /// Writes the given character to the output buffer.
  289. /// </summary>
  290. /// <param name="c">Character to write</param>
  291. public void Write(char c)
  292. {
  293. if (_preformatted)
  294. {
  295. // Write preformatted character
  296. _text.Append(c);
  297. }
  298. else
  299. {
  300. if (c == '\r')
  301. {
  302. // Ignore carriage returns. We'll process
  303. // '\n' if it comes next
  304. }
  305. else if (c == '\n')
  306. {
  307. // Flush current line
  308. FlushCurrLine();
  309. }
  310. else if (Char.IsWhiteSpace(c))
  311. {
  312. // Write single space character
  313. int len = _currLine.Length;
  314. if (len == 0 || !Char.IsWhiteSpace(_currLine[len - 1]))
  315. _currLine.Append(' ');
  316. }
  317. else
  318. {
  319. // Add character to current line
  320. _currLine.Append(c);
  321. }
  322. }
  323. }
  324. // Appends the current line to output buffer
  325. protected void FlushCurrLine()
  326. {
  327. // Get current line
  328. string line = _currLine.ToString().Trim();
  329. // Determine if line contains non-space characters
  330. string tmp = line.Replace(" ", String.Empty);
  331. if (tmp.Length == 0)
  332. {
  333. // An empty line
  334. _emptyLines++;
  335. if (_emptyLines < 2 && _text.Length > 0)
  336. _text.AppendLine(line);
  337. }
  338. else
  339. {
  340. // A non-empty line
  341. _emptyLines = 0;
  342. _text.AppendLine(line);
  343. }
  344. // Reset current line
  345. _currLine.Length = 0;
  346. }
  347. /// <summary>
  348. /// Returns the current output as a string.
  349. /// </summary>
  350. public override string ToString()
  351. {
  352. if (_currLine.Length > 0)
  353. FlushCurrLine();
  354. return _text.ToString();
  355. }
  356. }
  357. }
  358. //2、提取html的正文 类
  359. using System;
  360. using System.Text;
  361. namespace HtmlStrip
  362. {
  363. class MainClass
  364. {
  365. public static void Main (string[] args)
  366. {
  367. string str = "<div>abc</div><span>efg</span><br /><script>888</script><!--<PA>WW</PA-->oo";
  368. //System.IO.StreamReader rd=new System.IO.StreamReader ("/home/lx/test.html");
  369. //str=rd.ReadToEnd ();
  370. HtmlParser t = new HtmlParser (str); //
  371. t.KeepTag (new string[] { "br" }); //设置br标签不过虑
  372. Console.Write (t.Text ());
  373. }
  374. }
  375. class HtmlParser
  376. {
  377. private string[] htmlcode; //把html转为数组形式用于分析
  378. private StringBuilder result = new StringBuilder ();  //输出的结果
  379. private int seek; //分析文本时候的指针位置
  380. private string[] keepTag;  //用于保存要保留的尖括号内容
  381. private bool _inTag;  //标记现在的指针是不是在尖括号内
  382. private bool needContent = true;  //是否要提取正文
  383. private string tagName;  //当前尖括号的名字
  384. private string[] specialTag = new string[] { "script", "style", "!--" };  //特殊的尖括号内容,一般这些标签的正文是不要的
  385. /// <summary>
  386. /// 当指针进入尖括号内,就会触发这个属性。这里主要逻辑是提取尖括号里的标签名字
  387. /// </summary>
  388. public bool inTag {
  389. get { return _inTag; }
  390. set {
  391. _inTag = value;
  392. if (!value)
  393. return;
  394. bool ok = true;
  395. tagName = "";
  396. while (ok) {
  397. string word = read ();
  398. if (word != " " && word != ">") {
  399. tagName += word;
  400. } else if (word == " " && tagName.Length > 0) {
  401. ok = false;
  402. } else if (word == ">") {
  403. ok = false;
  404. inTag = false;
  405. seek -= 1;
  406. }
  407. }
  408. }
  409. }
  410. /// <summary>
  411. /// 初始化类
  412. /// </summary>
  413. /// <param name="html">
  414. ///  要分析的html代码
  415. /// </param>
  416. public HtmlParser (string html)
  417. {
  418. htmlcode = new string[html.Length];
  419. for (int i = 0; i < html.Length; i++) {
  420. htmlcode[i] = html[i].ToString ();
  421. }
  422. KeepTag (new string[] {  });
  423. }
  424. /// <summary>
  425. /// 设置要保存那些标签不要被过滤掉
  426. /// </summary>
  427. /// <param name="tags">
  428. ///
  429. /// </param>
  430. public void KeepTag (string[] tags)
  431. {
  432. keepTag = tags;
  433. }
  434. /// <summary>
  435. ///
  436. /// </summary>
  437. /// <returns>
  438. /// 输出处理后的文本
  439. /// </returns>
  440. public string Text ()
  441. {
  442. int startTag = 0;
  443. int endTag = 0;
  444. while (seek < htmlcode.Length) {
  445. string word = read ();
  446. if (word.ToLower () == "<") {
  447. startTag = seek;
  448. inTag = true;
  449. } else if (word.ToLower () == ">") {
  450. endTag = seek;
  451. inTag = false;
  452. if (iskeepTag (tagName.Replace ("/", ""))) {
  453. for (int i = startTag - 1; i < endTag; i++) {
  454. result.Append (htmlcode[i].ToString ());
  455. }
  456. } else if (tagName.StartsWith ("!--")) {
  457. bool ok = true;
  458. while (ok) {
  459. if (read () == "-") {
  460. if (read () == "-") {
  461. if (read () == ">") {
  462. ok = false;
  463. } else {
  464. seek -= 1;
  465. }
  466. }
  467. }
  468. }
  469. } else {
  470. foreach (string str in specialTag) {
  471. if (tagName == str) {
  472. needContent = false;
  473. break;
  474. } else
  475. needContent = true;
  476. }
  477. }
  478. } else if (!inTag && needContent) {
  479. result.Append (word);
  480. }
  481. }
  482. return result.ToString ();
  483. }
  484. /// <summary>
  485. /// 判断是否要保存这个标签
  486. /// </summary>
  487. /// <param name="tag">
  488. /// A <see cref="System.String"/>
  489. /// </param>
  490. /// <returns>
  491. /// A <see cref="System.Boolean"/>
  492. /// </returns>
  493. private bool iskeepTag (string tag)
  494. {
  495. foreach (string ta in keepTag) {
  496. if (tag.ToLower () == ta.ToLower ()) {
  497. return true;
  498. }
  499. }
  500. return false;
  501. }
  502. private string read ()
  503. {
  504. return htmlcode[seek++];
  505. }
  506. }
  507. }

引文原址:http://blog.csdn.net/cjh200102/article/details/6824895

HTML 转文本及HTML内容提取(C#)的更多相关文章

  1. python利用正则表达式提取文本中特定内容

    正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. re 模块使 Python ...

  2. 关于MFC文本框输入内容的获取 与 设置文本框的内容

    八月要开始做界面了<( ̄︶ ̄)/,然而目前只会用MFC╮(╯▽╰)╭ 好吧,言归正传,设置好文本框后,要获取用户输入的内容,可以用: GetDlgItemText() ; 这个函数有两个参数,第 ...

  3. jquery获取文本框的内容

    使用jquery获取文本框的内容有以下几种: 1.根据ID取值(id属性): // javascript <script type="text/javascript"> ...

  4. jQuery清除文本框,内容并设置不可用

    JQuery清除文本框,内容并设置不可用  如果是设置只读,则将disabled换成readonly function CleanText(textid) { $("#"+text ...

  5. Python即时网络爬虫项目: 内容提取器的定义(Python2.7版本)

    1. 项目背景 在Python即时网络爬虫项目启动说明中我们讨论一个数字:程序员浪费在调测内容提取规则上的时间太多了(见上图),从而我们发起了这个项目,把程序员从繁琐的调测规则中解放出来,投入到更高端 ...

  6. Python即时网络爬虫项目: 内容提取器的定义

    1. 项目背景 在python 即时网络爬虫项目启动说明中我们讨论一个数字:程序员浪费在调测内容提取规则上的时间,从而我们发起了这个项目,把程序员从繁琐的调测规则中解放出来,投入到更高端的数据处理工作 ...

  7. API例子:用Java/JavaScript下载内容提取器

    1,引言 本文讲解怎样用Java和JavaScript使用 GooSeeker API 接口下载内容提取器,这是一个示例程序.什么是内容提取器?为什么用这种方式?源自Python即时网络爬虫开源项目: ...

  8. .Net 文本框实现内容提示(仿Google、Baidu)

    原文:.Net 文本框实现内容提示(仿Google.Baidu) 1.Demo下载: 文本框实现内容提示(仿Google.Baidu).rar 2.创建数据库.表(我用的sqlserver2008数据 ...

  9. shell编程系列11--文本处理三剑客之sed利用sed删除文本中的内容

    shell编程系列11--文本处理三剑客之sed利用sed删除文本中的内容 删除命令对照表 命令 含义 1d 删除第一行内容 ,10d 删除1行到10行的内容 ,+5d 删除10行到16行的内容 /p ...

随机推荐

  1. Oracle 错误码

    Oracle作为一款比较优秀同时也比较难以掌握的大型数据库,在我们学习使用的过程中,不可避免的会遇到一些错误,为此 Oracle 给出了一套完备的错误消息提示机制 我们可以根据Oracle给出的消息提 ...

  2. GET——token

    private function get_token(){ $appid="wx4dae5d61b7f9935c"; $appSecret="24a91315a1a62a ...

  3. 移动端web页面使用position:fixed问题总结

    近期完成了一个新的项目(搜狐直播),其中又涉及到了 fixed(固定位置定位)的问题,在之前的文章<移动Web产品前端开发口诀——“快”>中已经阐述过我对 iScroll 的态度,所以在这 ...

  4. php经典面试题

    1. 用PHP打印出前一天的时间,打印格式是2007年5月10日 22:21:21 2. PHP代码如下:$a="hello"; $b=&$a;unset($b);$b=& ...

  5. C++通过OCCI操作Oracle数据库详解

    1.安装OCCI 如果oracle数据库默认没有安装OCCI,可以自己从官网上下载与自己数据库版本一致的API,其中包含四个软件包: oracle-instantclient-sqlplus-10.2 ...

  6. Android 常用对话框Dialog封装

    Android 6种 常用对话框Dialog封装 包括: 消息对话框.警示(含确认.取消)对话框.单选对话框. 复选对话框.列表对话框.自定义视图(含确认.取消)对话框 分别如下图所示:       ...

  7. C51库函数积累

    C51库函数积累: (1)_chkfloat_: 函数定义:unsigned char _chkfloat_ ( float val); /* number to check */ 函数功能:_chk ...

  8. qt-solutions提供了8个开源项目

    其实这是官方提供的源代码,至于为什么会另建项目,而没有整合到QT项目里去,我猜可能有2个原因: 1. 这几个项目本身不完善,并且也不是QT项目的核心,因此没有必要花精力去完善 2. 一定程度上可以维护 ...

  9. activity5 流程 入门

    http://blog.csdn.net/yangyi22/article/details/9225849 谢谢原文作者提供!

  10. 学习下关于ViewStub实例的用法及带Drawable的TextView的妙用

    在项目中,我们可能有多种数据来源比如: 里面有ListView也有当获得数据为空的时候显示的空信息.根据点击的项目还是差事不同,显示的空消息也不同.a.没有收藏的项目,b目前没有收藏的差事. 其实实现 ...