今天遇到个好玩的问题,java中String类有个replaceAll(A,B)函数,顾名思义,是将一个String对象中的A全部换成B。没问题,我们来做个测试,代码如下:
public class Test{
public static void main(String args[]){
String a = "nan nan nan nan";
a = a.replaceAll("nan", "dong nan");
System.out.println(a);
}
};
将字符串a中的所有nan替换成dong nan,
结果:dong nan dong nan dong nan dong nan
结果没有任何问题。但是我们现在改变一下要求,有个字符串:String a = "A nan A nAn A A A";其中,”A” 是字符串”A B C”缩写,要求把上面字符串中的缩写全部替换成全拼
理论上的要求替换结果是:”A B C nan A B C nAn A B C A B C A B C”
字符串”nAn”中的A不算缩写,这里规定,缩写应该是一个或者多个单词,而且,如果这个缩写不是在开头或者结尾的话,缩写的字符串两边是应该都有空格或者其他分隔字符的(本例的分隔字符就是空格)。
我们继续用上面的代码进行替换
public class Test{
public static void main(String args[]){
String a = "A nan A nAn A A A";
a = a.replaceAll("A", "A B C");
System.out.println(a);
}
};
要求把是缩写的A全部替换成”A B C”,
结果:A nan A B C nA B Cn A B C A B C A B C
不符合要求,因为”nAn”中的A也被替换了,我们改一下
public class Test{
public static void main(String args[]){
String a = "A nan A nAn A A A";
a = a.replaceAll(" A ", " A B C ");//字符串开头结尾各加上一个空格
System.out.println(a);
}
};
结果:A nan A B C nAn A B C A A
注意上面,标为红的A没有被替换掉。replaceAll函数失效了?我们来分析一下原始字符串
Anan A nAn A A A
以上字符串红色的A都是需要被替换的,但是,结果是第四个红色的A没有被替换成功,它两边都有空格,符合被替换的条件,但是,初步分析,java的String的replaceAll函数的实现应该是这样的:当替换到第三个A时,这个A后面的空格也被替换掉了(因为我们是替换的“ A ”,两边空格也被替换),所以第四个A前面的空格是被替换过的,替换过的是不在进行替换的,如果用C++中指针来直观的表示,那就是这时候指针指到了第四个A,而不是第四个A前面的空格,因此,第四个A是不能被替换掉的。
一个办法就是,循环调用repalceAll函数,进行替换,循环的条件就是检查字符串中是否还存在缩写。这种办法大部分情况下可以正常工作,但是,在本例中是不行,程序会死循环,因为缩写A所对应的全拼A B C中也有A,这样就会死循环。
这里,我们用到一个简单的办法就是,将原始字符串中的空格,全部先替换成两个空格,然后再调用replaceAll函数替换所有缩写。
代码就是这样:
public class Test{
public static void main(String args[]){
String a = "A nan A nAn A A A";
a = a.replaceAll(" ", " ");//一个空格变两个
a = a.replaceAll(" A ", " A B C ");
a = a.replaceAll(" ", " ");//变回来
System.out.println(a);
}
};
结果:A nan A BC nAn A B C A B C A
第四个A成功被替换换。
至于开头和结尾的两个A,替换方法如下:
public class Test{
public static void main(String args[]){
String a = "A nan A nAn A A A";
a = a.replaceAll(" ", " ");//
a = a.replaceAll(" A ", " A B C ");
a = a.replaceAll(" ", " ");//
a = a.replaceAll("^A ", "A B C ");//替换开头
a = a.replaceAll(" A$", " A B C");//替换结尾
System.out.println(a);
}
};
结果:A B C nan A B C nAn A B C A B C A B C
注意,开头和结尾的替换,应该放在最后,不然,造成的结果请自己测试。