昨天系统报错,No group 6,上网查询,说是replaceAll()的问题,就具体试验了一下,发现如果不注意,就会产生隐含的错误。
java的String类的replaceAll方法是一个挺常用的方法,类型定义如下:
String replaceAll(String regex, String replacement)
有两个参数,第一个是被替换的字符串,是正则表达式,另外一个是替换成的字符串。
如果我们这样写:
upLoadedFileName.replaceAll("////","/"); // 把//替换为/
是没有什么问题的,而且用好正则表达式可以实现很强的功能,如:
str.replaceAll("(?i)"+oldStr,newStr);//忽略大小写;
但是,使用中我们一定要记住,不仅仅第一个参数是正则表达式,第二个也是,因此如果这两个是可变参数,就要注意参数的内容,一篇文档说应该在所有的[ / ^ $ . | ? * + ( ) { }符号前面加上/符号。经过我的测试(jdk1.4),只有/和$容易出错。
比如:
System.out.println("/".replaceFirst("/", "//"));
系统会报:java.lang.StringIndexOutOfBoundsException: String index out of range: 1
System.out.println("/".replaceFirst("/", "x//"));
系统会报:java.lang.StringIndexOutOfBoundsException: String index out of range: 2
System.out.println("/".replaceFirst("/", "//X"));
执行结果是X
System.out.println("/".replaceFirst("/", "$6"));
执行结果抛出例外:java.lang.IndexOutOfBoundsException: No group 6
所以如果参数是变量,而且可能包含/或$,建议不要使用replaceAll和replaceFirst方法。
我实现了这两个方法,大家可以直接引用。
/**
* 字符串替换,从头到尾查询一次,替换后的字符串不检查
* @param str 源字符串
* @param oldStr 目标字符串
* @param newStr 替换字符串
* @return 替换后的字符串
*/
static public String replaceAll(String str, String oldStr, String newStr)
{
int i = str.indexOf(oldStr);
int n = 0;
while(i != -1)
{
str = str.substring(0, i) + newStr + str.substring(i + oldStr.length());
i = str.indexOf(oldStr, i + newStr.length());
n++;
}
return str;
}
/**
* 字符串替换,左边第一个。
* @param str 源字符串
* @param oldStr 目标字符串
* @param newStr 替换字符串
* @return 替换后的字符串
*/
static public String replaceFirst(String str, String oldStr, String newStr)
{
int i = str.indexOf(oldStr);
if (i == -1) return str;
str = str.substring(0, i) + newStr + str.substring(i + oldStr.length());
return str;
}
System.out.println(StringTools.replaceAll("/","/","//"));
结果是/