`

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

    博客分类:
  • java
阅读更多
需求一:

数据库中存储有一段带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();
}
}
分享到:
评论

相关推荐

    php对包含html标签的字符串进行截取的函数分享

    - 使用`mb_strlen`函数计算字符串的长度,考虑中英文字符。 - 如果字符串长度小于截取长度,直接返回原字符串。 - 检查字符串是否包含HTML标签,如果没有,直接使用`mb_substr`进行截取。 - 初始化变量,如`$...

    PHP HTML代码串 截取实现代码

    截取时不仅要保留文本内容,还要保持HTML标签的正确性和完整性,这意味着在截取文本的过程中不能破坏原有的HTML结构。 ### 字符串遍历方法的局限性 传统的截取方法可能会通过遍历字符串的每个字符,并使用标记来...

    php 截取utf-8格式的字符串实例代码

    为了解决UTF-8编码字符串截取的问题,需要特别注意的是,UTF-8编码下的多字节字符在被截取时,必须同时保留字符的完整性。由于一个UTF-8编码的字符可能由1到4个字节组成,所以不能以字节为单位进行简单的截取操作。 ...

    JavaScript笔记

    1.单击事件:定义在按钮的开始标签中 语法:onclick="js语句" 弹出警告:alert&#40;‘字符串’&#41; 强调:1.js区分大小写 2.字符串单双引号不区分 [removed]标签:页面中专门集中编写JavaScript的区域 js的...

    EXCEL集成工具箱V8.0完整增强版(精简)

    支持中英文显示与繁简体操作系统、拥有20多款华丽的皮肤界面,支持Excel2007全面 隐藏选项卡,这个插件还模拟了一个Excel2003样式的菜单,目的就是方便那些从Excel2003转向使用2007或2010版的朋友使用。 ========...

    正则表达式大全

    - **HTML标签去除**:使用正则表达式去除HTML字符串中的标签。 - **空白字符移除**:字符串trim方法的自定义实现,移除前后空白字符。 - **IP地址转换**:将点分十进制IP地址转换为数值表示,便于比较和排序。 通过...

    EXCEL集成工具箱V6.0

    支持中英文显示与繁简体操作系统、拥有20多款华丽的皮肤界面,支持Excel2007全面 隐藏选项卡,这个插件还模拟了一个Excel2003样式的菜单,目的就是方便那些从Excel2003转向使用2007或2010版的朋友使用。 ========...

    PHP读取txt文本文件并分页显示的方法

    3. 字符串截取函数:实现分页的一个核心函数是msubstr(),这个函数通过参数指定的起始位置和长度来截取字符串。该函数在处理字符串时还考虑到了中文字符通常占用两个字节的情况,故在截取时能够正确处理中文字符。 ...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part1

    实例112 解决用substr()函数对中文字符串截取时出现乱码的问题 143 实例113 字符串与HTML标记相互转换 144 实例114 运用PHP 5.0新型字符串输出XML数据 145 实例115 判断字符串中是否存在指定子串 146 2.9 正则表达式...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    实例112 解决用substr()函数对中文字符串截取时出现乱码的问题 143 实例113 字符串与HTML标记相互转换 144 实例114 运用PHP 5.0新型字符串输出XML数据 145 实例115 判断字符串中是否存在指定子串 146 2.9 正则表达式...

    2021-2022计算机二级等级考试试题及答案No.10956.docx

    14. 赋值语句`a=123&MID("123456",3,2)`,`MID`函数截取字符串,得到`34`,与123按位与运算得到157,但答案是C,可能是因为题目中`MID`函数的使用有误,实际应为`a=123&MID("123456",3,2)`,得到12334。 15. 对长度...

    2021-2022计算机二级等级考试试题及答案No.2086.docx

    13. **字符串截取操作**:题目通过具体的字符串操作示例来考察字符串处理能力。正确答案是B,即截取字符串中特定位置之后的部分。 ### 公式填充功能 14. **Excel中的公式填充**:在Excel中,可以通过拖动单元格右下...

    jsp强行给表格换行

    - 函数内部通过循环不断截取字符串,并在每一段后面添加` `标签,从而实现换行效果。 - 最后通过`document.getElementById("ff")`获取指定元素,并更新其`innerHTML`属性,完成换行处理。 #### 注意事项 - 在...

    2021-2022计算机二级等级考试试题及答案No.15098.docx

    18. VisualBasic6.0中,使用LEFT函数可以从字符串中截取子串,如LEFT("Visual Basic 6.0", 6)会返回"Visual"。 19. AUTO_INCREMENT属性在MySQL中用于自动递增主键,如果插入值为0或省略,数据库会自动生成下一个值...

    WordPress 文章摘要功能实现代码

    echomb_strimwidth()函数负责根据指定的字符数限制截取文本,而strip_tags()函数则确保输出的摘要中不包含任何HTML标签。apply_filters()函数则是WordPress内置的一个钩子(hook),可以对文章内容进行过滤处理。 ...

    Tinyxml 源代码(VC6 & VS2005)

    老版本的TinyXML“保留”了字符实体,而在新版本中它们会被转化成字符串。 另外,所有字符都可以用它的Unicode编码数字来指定, " "和" "都表示不可分的空格字符。 打印 TinyXML有几种不同的方式来打印输出,...

Global site tag (gtag.js) - Google Analytics