对整段内容进行匹配和替换

来源:互联网 发布:如何自己开淘宝网店 编辑:程序博客网 时间:2024/06/06 05:42

功能,在整段文本内容中,查找符合某些条件的内容,进行替换。需要注意的是,因为查找了替换是两个步骤,可能造成替换的内容并非查找的内容。

 

package com.shuwei.tools;import java.util.regex.Matcher;import java.util.regex.Pattern;/* * 对一段文本中的某些字符进行处理后,再替换 */public class BigContentReplace {public static void main(String[] args) {/*long startTime = System.currentTimeMillis();String content = "1111aa2222<a href='aa'></a>3333bb444<action='bbbb'/>555ccc'ccc'";for(int i = 0; i < 1000000; i++){replace1(content);}long endTime = System.currentTimeMillis();System.out.println(endTime - startTime);startTime = System.currentTimeMillis();for(int i = 0; i < 1000000; i++){replace2(content);}endTime = System.currentTimeMillis();System.out.println(endTime - startTime);*/String content1 = "1111aa2222<a href='aa'></a>3333bb444<action='bbbb'/>555ccc'ccc'";content1 = replace1(content1);System.out.println(content1);String content2 = "1111aa2222<a href='aa'></a>3333bb444<action='bbbb'/>555ccc'ccc'";content2 = replace2(content2);System.out.println(content2);}/* * 思路:先找出匹配组,然后对匹配项进行处理,最后对内容进行精确替换 * 优点:便于理解 * 缺点:操作步骤较多 */public static String replace1(String content){//将单引号中的内容使用encode后的内容替换//如:需要将下面content中的页面链接后面根据链接的字符数n加上n个T//由于需要根据对需要替换的字符进行处理,不能使用直接的content.replaceAll(),因为需要获得匹配的部分Pattern p = Pattern.compile("((href=)|(action=))'.*?'");Matcher m = p.matcher(content);while(m.find()){String target = m.group();int start = target.indexOf('\'');int end = target.indexOf('\'', start + 1);String replacement = target.substring(0, start + 1) + encode(target.substring(start + 1, end)) + target.substring(end);content = content.replace(target, replacement);}return content;}/** * 思路:先获得每次匹配时候字符串的长度,由于从前往后替换,每次替换后在实际的字符串中的位置会变动 * 所以需要保存原始字符串的长度和当前匹配内容的开始位置,计算差。然后再使用长度进行替换 * 需要注意的是,每次匹配的内容距离实际字符串尾部的位置是不会变的 * @param content * @return */public static String replace2(String content){Pattern p = Pattern.compile("((href=)|(action=))'(.*?)'");Matcher m = p.matcher(content);int length = content.length();while(m.find()){String target = m.group(4);/** * 这段代码会产生错位的问题--至于原因自己可以分析下 int start = m.start();int end = m.end();content = content.substring(0, start) + encode(target) + content.substring(end); */int dis = length - m.end();//当前字符串内容中的结束位置int currentEnd = content.length() - dis - 1;content = content.substring(0, currentEnd - target.length()) + encode(target) + content.substring(currentEnd);}return content;}public static String encode(String str){StringBuilder sb = new StringBuilder(str);for(int i = 0; i < str.length(); i++){sb.append("T");}return sb.toString();}}


replace1的思路相对比较容易理解,即匹配什么就对什么进行一次替换。

replace2采用拼接的做法,理解起来也不难,只是容易犯一个注释中的错误。

经测试,代码中的字符串替换100万次,使用replace1需要10秒钟,而使用replace2需要6秒钟,字符串内容多了性能差异应该更明显。所以尽量使用replace2方法。

使用StringBuilder对replace2进行优化

public static String replace2(String content){Pattern p = Pattern.compile("((href=)|(action=))'(.*?)'");Matcher m = p.matcher(content);StringBuilder sb = new StringBuilder(content);int length = content.length();while(m.find()){String target = m.group(4);/** * 这段代码会产生错位的问题--至于原因自己可以分析下 int start = m.start();int end = m.end();content = content.substring(0, start) + encode(target) + content.substring(end); */int dis = length - m.end();//当前字符串内容中的结束位置int currentEnd = sb.length() - dis - 1;int currentStart = currentEnd - target.length();sb.delete(currentStart, currentEnd);sb.insert(currentStart, encode(target));/*sb.delete(0, currentEnd - target.length()) + encode(target) + content.substring(currentEnd);*/}return sb.toString();}


在测试代码中,执行100万次replace2的时间仍然是6秒,可能因为测试数据的content比较短的原因。对于content比较大的时候性能应该会有提升。

原创粉丝点击