使用Replace方法时要注意的问题

      我们经常使用字符串的Replace方法,很多时候代码顺手就写出来了,很少去注意潜在的问题.

比如要把一个html文件的扩展名修改成txt文件,一般我们都会这样写: String s="test.html"; s.Replace(".html",".txt"); 这样写表面上看似乎没有太大问题,

一般来说,在很长的时间里都不会出问题,因为我们的程序或者用户都是用小写字母来创建扩展名.

但某天就有那么一个用户不按常规出牌,丢给程序一个"test.Html"的文件,这个时候问题就爆发了.

其实Replace方法在内部也是使用正则表达式来实现的,其源代码如下:

[Replace Source Code]      

代码
1 /**
2 * Replaces each substring of this string that matches the literal target
3 * sequence with the specified literal replacement sequence. The
4 * replacement proceeds from the beginning of the string to the end, for
5 * example, replacing "aa" with "b" in the string "aaa" will result in
6 * "ba" rather than "ab".
7 *
8 * @param target The sequence of char values to be replaced
9 * @param replacement The replacement sequence of char values
10 * @return The resulting string
11 * @throws NullPointerException if <code>target</code> or
12 * <code>replacement</code> is <code>null</code>.
13 * @since 1.5
14 */
15 public String replace(CharSequence target, CharSequence replacement) {
16 return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
17 this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
18 }
19  

从源代码可以看出,它是按照原文进行替换的,也就是说,要区分大小写. 恩,是的这个Replace方法是区分大小写的,但这点,我们经常会忘记.

写个单元测试来说明这个问题,以下代码使用一个不区分大小写的正则表达式来作为参照.

 

代码
1 public void testCompareReplace()
2 {
3 String s="test.HtML";
4 //字符串的Replace方法,在内部其实也是使用正则表达式来进行替换.只是,匹配模式是区分大小写的.
5   String test1=s.replace(".html", ".txt");
6
7 //这里,由于文件扩展名可能出现大写,小写,或者大小写混合.因此必须使我们的匹配模式不区分大小写.
8   Pattern pt=Pattern.compile("\\.html",Pattern.CASE_INSENSITIVE);
9 Matcher mt=pt.matcher(s);
10 String test2=mt.replaceAll(".txt");
11
12 assertEquals("test.txt", test1); //失败
13   assertEquals("test.txt", test2); //成功
14   }

 

 

 

其实字符串的替换,最好直接使用正则表达式的Replace,这样很容易控制和修改.

posted @ 2010-01-04 21:39  畅想自由  阅读(606)  评论(0编辑  收藏  举报