在开发中遇到的问题,问题已经解决了,但是深层原因还没搞懂,先记录下来慢慢沉淀!
java.lang.String.replaceAll(String regex,String replacement)
以下用几个demo来说明:
public class Test {
public static void main(String args[]){
String comment = "600444abc";
String a= "600444";
String key = "*abc";//**.?+$^()[]{}
String b = comment.replaceAll(a+ "|" + key, "<a>" + a + key +"</a>");
System.out.println(b);
}
}
运行结果:
问题原因:replaceAll的第一个参数是一个正则表达式,而变量key中包含正则表达式的特殊字符*,于是这个*不会被当成key的内容,而是当成了正则表达式的特殊字符,由于在正则表达式中*是不能放在表达式的开始位置,于是抛错了。
将正则表达式里所有特殊字符做处理后的demo如下:
public class Test {
public static void main(String args[]){
String comment = "600444abc";
String a= "600444";
String key = "*abc";//**.?+$^()[]{}
String b = comment.replaceAll(Escape(a)+ "|" + Escape(key), "<a>" + a + key +"</a>");
System.out.println(b);
}
private static String Escape(String a){
a = a.replaceAll("\\\\", "\\\\\\\\");
a = a.replaceAll("\\*", "\\\\*");
a = a.replaceAll("\\.", "\\\\.");
a = a.replaceAll("\\?", "\\\\?");
a = a.replaceAll("\\+", "\\\\+");
a = a.replaceAll("\\$", "\\\\\\$");
a = a.replaceAll("\\^", "\\\\^");
a = a.replaceAll("\\[", "\\\\[");
a = a.replaceAll("\\]", "\\\\]");
a = a.replaceAll("\\(", "\\\\(");
a = a.replaceAll("\\)", "\\\\)");
a = a.replaceAll("\\{", "\\\\{");
a = a.replaceAll("\\}", "\\\\}");
a = a.replaceAll("\\|", "\\\\|");
return a;
}
}
运行结果:
通过特殊字符转义后运行正常,再一一测试其他特殊字符.?+$^|\()[]{},发现仅$通不过,demo如下:
public class Test {
public static void main(String args[]){
String comment = "600444abc";
String a= "600444";
String key = "$abc";//**.?+$^()[]{}
String b = comment.replaceAll(Escape(a)+ "|" + Escape(key), "<a>" + a + key +"</a>");
System.out.println(b);
}
private static String Escape(String a){
a = a.replaceAll("\\\\", "\\\\\\\\");
a = a.replaceAll("\\*", "\\\\*");
a = a.replaceAll("\\.", "\\\\.");
a = a.replaceAll("\\?", "\\\\?");
a = a.replaceAll("\\+", "\\\\+");
a = a.replaceAll("\\$", "\\\\\\$");
a = a.replaceAll("\\^", "\\\\^");
a = a.replaceAll("\\[", "\\\\[");
a = a.replaceAll("\\]", "\\\\]");
a = a.replaceAll("\\(", "\\\\(");
a = a.replaceAll("\\)", "\\\\)");
a = a.replaceAll("\\{", "\\\\{");
a = a.replaceAll("\\}", "\\\\}");
a = a.replaceAll("\\|", "\\\\|");
return a;
}
}
运行结果:
百思不得其解,当key无论被赋什么值,无论这些特殊字符怎么组合只要没有$就可以通过。发现把replaceAll的第一个参数的“或”去掉,$符号就可以通过了。但是在业务逻辑中”或“是必须要使用的。
String b = comment.replaceAll(Escape(a)+ "" + Escape(key), "<a>" + a + key +"</a>");//$可以通过
后来小组经理告诉我可以用:StringUtils.replace(String text, String searchString, String replacement);这个方法也可以替换,StringUtils属于org.apache.commons.lang.StringUtils包。但是这个replace没有正则表达式,达不到”或“的业务需要,如果通过两次raplace那么第一次替换的结果会影响到第二次替换,不符合需求。
后来发现replaceAll的第二个参数也需要特殊字符转义,解决demo如下:
public class Test {
public static void main(String args[]){
String comment = "600444abc";
String a= "600444";
String key = "$abc";//**.?+$^()[]{}
String b = comment.replaceAll(Escape(a)+ "|" + Escape(key), Escape("<a>" + a + key +"</a>"));
System.out.println(b);
}
private static String Escape(String a){
a = a.replaceAll("\\\\", "\\\\\\\\");
a = a.replaceAll("\\*", "\\\\*");
a = a.replaceAll("\\.", "\\\\.");
a = a.replaceAll("\\?", "\\\\?");
a = a.replaceAll("\\+", "\\\\+");
a = a.replaceAll("\\$", "\\\\\\$");
a = a.replaceAll("\\^", "\\\\^");
a = a.replaceAll("\\[", "\\\\[");
a = a.replaceAll("\\]", "\\\\]");
a = a.replaceAll("\\(", "\\\\(");
a = a.replaceAll("\\)", "\\\\)");
a = a.replaceAll("\\{", "\\\\{");
a = a.replaceAll("\\}", "\\\\}");
a = a.replaceAll("\\|", "\\\\|");
return a;
}
}
运行结果:
再后来发现这样也跟上面的代码达到相同结果,demo如下:
import org.apache.commons.lang.StringUtils;
public class Test {
public static void main(String args[]){
String comment = "600444abc";
String a= "600444";
String key = "$**.?+$^()[]{}abc\\";//**.?+$^()[]{}
String[] searchList = {a,key};
String replacementList[] = {"<a>" + a + key +"</a>","<a>" + a + key +"</a>"};
//String b = comment.replaceAll(Escape(a)+ "|" + Escape(key), Escape("<a>" + a + key +"</a>"));
//System.out.println(b);
String c = StringUtils.replaceEach(comment, searchList, replacementList);
System.out.println(c);
}
}