惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Blog — PlanetScale
Blog — PlanetScale
G
Google Developers Blog
Microsoft Security Blog
Microsoft Security Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
腾讯CDC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Jina AI
Jina AI
雷峰网
雷峰网
T
Tailwind CSS Blog
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
酷 壳 – CoolShell
酷 壳 – CoolShell
大猫的无限游戏
大猫的无限游戏
月光博客
月光博客
博客园 - 司徒正美
I
InfoQ
Engineering at Meta
Engineering at Meta
Vercel News
Vercel News
小众软件
小众软件
U
Unit 42
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net

博客园 - 畅想自由

为什么19.9变成了19.89,不靠谱的 double 类型 HashTable Thinking in Java HTML已经过时了 编写高质量的.NET程序 - 开篇 Do not make joke with me 告别.NET Tomcat 部署问题记录 最近在看的书 经济危机,让我们更加清醒 早上醒来,突然睡不着 IE和FireFox 对动态FORM enctype属性的认识问题 - 畅想自由 不再技术崇拜,精神开始焕发 Vs2003中Grid绑定强类型的问题 青春的岁月我们身不由己,只因着心中燃烧着梦想... 职业规划是什么? 做一个专业的IT管理人才必备的十大能力 Delphi的类与继承 Delphi 与 C#
使用Replace方法时要注意的问题 - 畅想自由 - 博客园
畅想自由 · 2010-01-04 · via 博客园 - 畅想自由

      我们经常使用字符串的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,这样很容易控制和修改.