注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

无线时代辐射无穷

抓紧生宝宝,小心辐射

 
 
 

日志

 
 

带html标签的中英文字符串截取之完整性  

2009-12-09 14:40:58|  分类: java |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

需求一:

数据库中存储有一段带html标签的文字,如:

<P>《Windows》系统是越用越慢,这是不争的事实。</P> <P>因此,使用Win<font size='12pt'>d</font>ows就免不<img src='http:/www.blueidea.com/img/common/logo.gif'/>了要重新安装系统。<br>当然<span style='border:solid 1px red;font-size:23px'>,重新安装系</span>统并不难,但是安装完系统后你知道我<h1>们</h1>有多少事情必须要做吗?<br><strong>这</strong>可容不得丝毫的松懈,一旦马虎,将可能会导致前功尽弃,甚至有可能会造成数据丢失、信息泄密!</P>

现在要把它的前n个实际意义(即不包括html标签)的字符取出来,而且不能破坏它的段落标记,也就是说该是几段还是几段,p标签不算做n个字之内,又不能去掉

常见处:

新闻、小说、博客等的首页列表

代码:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HtmlTagRemove {
 /**
  * @function  出入口函数,获取文章的导读(前段文字)
  * @param str 文章字符串
  * @param length 导读长度
  * @return 文章导读
  */
 public String getNevigation(String str,int length){
 
  //去掉除p以外的其他html标签
  str = removeHtmlTagExceptP(str);
 
  //获取导读
  str = getHeadSubStr(str, length);
 
  //补充导读中的P标签
  str = repairPTag(str);
 
  return str;
 }

 /**
  * 函数说明:去掉p以外的其他标签
  * @param 带html标签的字符串
  * @return 处理后的字符串
  */
 public String   removeHtmlTagExceptP(String   htmlstr)   {
  //正则说明:\s 空白字符,  . 任何字符, * 零次或多次, ? 一次或一次也没有 ,*? 零次或多次  ,^ 除   之外
 
        //Pattern   pat   =   Pattern.compile("\\s">\\s*<[^p].*?[^p]>\\s*", Pattern.DOTALL |   Pattern.MULTILINE   | Pattern.CASE_INSENSITIVE);
  Pattern   pat   =   Pattern.compile("\\s">\\s*</?+[^p].*?>\\s*", Pattern.DOTALL |   Pattern.MULTILINE   | Pattern.CASE_INSENSITIVE);
       
        //\\s?[s|Sc|Cr|Ri|Ip|Pt|T]  
        Matcher   m   =   pat.matcher(htmlstr);  
        //去掉所有html标记  
        String   rs   =   m.replaceAll("");  
        rs   =   rs.replaceAll("&nbsp",   " ");  
        rs   =   rs.replaceAll("&lt;",   "<");  
        rs   =   rs.replaceAll("&gt;",   ">");  
        return   rs;  
    } 
 /**
  * 函数说明:获取字符串的前一段文字
  * @param str 目标字符串
  * @param subLen 获取文字的长度
  * @return 得到的字符串
  */
 public String  getHeadSubStr(String str,int subLen){
  StringBuffer strBuffer =new StringBuffer();
  int count=0;
  for(int i=0;str!=null&&i<str.length();){
   char c = str.charAt(i);  
   if(c=='<'&&str.charAt(i+1)=='p'&&str.charAt(i+2)=='>'){
   
   
      strBuffer.append(c);
      strBuffer.append(str.charAt(i+1));
      strBuffer.append(str.charAt(i+2));
      i+=3;
      continue;
   }    
   if(c=='<'&&str.charAt(i+1)=='/'&&str.charAt(i+2)=='p'&&str.charAt(i+3)=='>'){
    
       strBuffer.append(c);
       strBuffer.append(str.charAt(i+1));
       strBuffer.append(str.charAt(i+2));
       strBuffer.append(str.charAt(i+3));
       i+=4;
       continue;     
   }
   strBuffer.append(c);
   i++;
   if(++count==subLen){
    break;
   }
  }
  return strBuffer.toString();
 }
 /**
  * 方法说明:修补获取的字符串(主要是匹配p标签)
  * @param str 目标字符串
  * @return 修补后的字符串
  */
 public String repairPTag(String str){
 
  //判断截取的字符串p标签是否完整
  String lastSubStr = str.substring(str.length()-3);
  if(!lastSubStr.equals("</p>")){
   str = str+"</p>";
  }
  return str;
 }
}

 

需求二:数据库中存储一段带有html标签的文字,要从中取出前n个字符,且需保证一:html标签完整,不能出现如:<img hre后面被截断的情况,二:标签匹配 不允许出现如:<font ...>而不存在后面的</font>


import java.util.Stack;

public class StringHTML
{
 public static void main(String[] args)
 {
  StringHTML stringHTML = new StringHTML();
  String str = "<P>《Windows》系统是越用越慢,这是不争的事实。</P> <P>因此,使用Win<font size='12pt'>d</font>ows就免不<img src='http:/www.blueidea.com/img/common/logo.gif'/>了要重新安装系统。<br>当然<span style='border:solid 1px red;font-size:23px'>,重新安装系</span>统并不难,但是安装完系统后你知道我<h1>们</h1>有多少事情必须要做吗?<br><strong>这</strong>可容不得丝毫的松懈,一旦马虎,将可能会导致前功尽弃,甚至有可能会造成数据丢失、信息泄密!</P>";
  System.out.println("str=" + str);
  System.out.println("str=" + stringHTML.subHtmlStr(str, 10));
  System.out.println("str=" + stringHTML.subHtmlStr(str, 20));
  System.out.println("str=" + stringHTML.subHtmlStr(str, 30));
  System.out.println("str=" + stringHTML.subHtmlStr(str, 50));
 }

 /**
  * 方法说明:出入口函数,获取html标签完整的导读 参数说明:str 目标字符串 参数说明:leng 导读的长度 返回值: html标签完整的字符串
  */
 public String subHtmlStr(String str, int length)
 {
  Stack<Character> charStack = new Stack<Character>(); //定义存储字符的栈
  Stack<String> stringStack = new Stack<String>(); //定义存储字符串的栈
  str = getNavigWithCorrectTag(str, length, charStack);
  str = repairNavigition(str, stringStack);
  return str;
 }

 /**
  * @function 获取导读,保证标签不被破坏
  * @param str 目标字符串
  * @param length 导读的长度
  * @return 标签不被破坏的字符串
  */
 //保证标签的正确
 public String getNavigWithCorrectTag(String str, int length, Stack<Character> charStack)
 {
  StringBuffer strBuffer = new StringBuffer();
  int count = 0; //统计取到的字符数 
  for (int i = 0; str != null; i++)
  {
   char c = str.charAt(i);
   if (c == '<')
   {
    //入栈操作
    charStack.push(c);
   }
   if (c == '>')
   {
    //出栈操作
    charStack.pop();
   }
   strBuffer.append(c);
   if (c > 126 || c < 33)
   {
    count += 2;
   }
   else
   {
    count += 1;
   }
   if (i >= str.length())
   {
    break;
   }
   else
   {
    if (count >= length)
    {
     //空栈时
     if (charStack.isEmpty())
     {
      break;
     }
    }
   }
  }
  return strBuffer.toString();
 }

 /**
  * @function 进一步匹配标签
  * @param str 目标字符串
  * @return 匹配好标签的字符串
  */
 public String repairNavigition(String str, Stack<String> stringStack)
 {
  //初始化字符串栈
  StringBuffer strBuffer = new StringBuffer();
  for (int i = 0; str != null && i < str.length();)
  {
   char c = str.charAt(i);
   //逐个获取html标签
   if (c == '<')
   {
    String tempStr = "";
    tempStr = tempStr + c;
    while (true)
    {
     i = i + 1;
     tempStr += str.charAt(i);
     if (str.charAt(i) == '>')
     {
      i++;
      break;
     }
    }
    if (!(tempStr.equalsIgnoreCase("<br>") || tempStr.equalsIgnoreCase("<hr>")))
    {
     //非br\hr标签时    
     if (!(tempStr.contains("</")) && !tempStr.contains("/>"))
     {
      //起始标签时入栈
      stringStack.push(tempStr);
      //存储
      strBuffer.append(tempStr);
     }
     else
     {
      //结束标签时,取栈顶元素
      String startTag = stringStack.peek();
      //取出temStr的2至length-1子串并判断是否匹配,看是否包含在栈顶元素中,若包含则匹配     
      if (startTag.contains(tempStr.substring(2, tempStr.length() - 1)))
      {
       //匹配时出栈
       stringStack.pop();
       strBuffer.append(tempStr);
      }
      else
      {
       //不匹配时说明当前标签是个单标签,直接加入
       strBuffer.append(tempStr);
      }
     }
    }
    else
    {
     //br hr 标签直接加入
     strBuffer.append(tempStr);
    }
   }
   else
   {
    //普通字符时直接加入
    strBuffer.append(str.charAt(i++));
   }
  }
  //当栈不为空时,说明有未匹配的标签
  while (!stringStack.isEmpty())
  {
   //取栈顶
   String startTag = stringStack.peek();
   //构造与之对应的结束标签
   for (int j = 0; j < startTag.length(); j++)
   {
    if (startTag.charAt(j) != ' ' && startTag.charAt(j) != '>')
    {
     strBuffer.append(startTag.charAt(j));
    }
    else
    {
     break;
    }
   }
   strBuffer.append("/>");
   //栈顶元素出栈
   stringStack.pop();
  }
  return strBuffer.toString();
 }
}

参考资料:

http://blog.csdn.net/fhm727/archive/2009/09/29/4616396.aspx

http://blog.csdn.net/fhm727/archive/2009/09/29/4616720.aspx

 

  评论这张
 
阅读(900)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017