字符串的操作,诸如追加、合并、替换、倒序、分割等,都是在编码过程中经常用到的,而且Java也提供了append、replace、reverse、split等方法来完成这些操作,它们使用起来也确实方便,但是更多的时候,需要使用正则表达式来完成复杂的处理,我们来看一个例子:统计一篇文章中英文单词的数量,很简单吧?代码如下:
public static void main(Stringargs){
//接收键盘输入
Scanner input=new Scanner(System.in);
while(input.hasNext()){
String str=input.nextLine();
//使用split方法分隔后统计
int wordsCount=str.split("").length;
System.out.println(str+"单词数:"+wordsCount);
}
}
使用split方法根据空格来分割单词,然后计算分隔后的数组长度,这种方法可靠吗?可行吗?我们来看输出:
Today is Monday
Today is Monday单词数:3
Today is Monday
Today is Monday单词数:4
Today is Monday?No!
Today is Monday?No!单词数:3
I'm Ok.
I'm Ok.单词数:2
注意看输出,除了第一个输入"Todady is Monay"正确外,其他都是错误的!第二条输入中单词"Monday"前有2个连续的空格,第三条输入中"NO"单词的前后都没有空格,最后一个输入则没有把连写符号“'”考虑进去,这样统计出来的单词数量肯定错误一堆,那怎么做才合理呢?
如果考虑使用一个循环来处理这样的“异常”情况,会使程序的稳定性变差,而且要考虑太多太多的因素,这让程序的复杂性也大大提高了。那如何处理呢?可以考虑使用正则表达式,代码如下:
public static void main(Stringargs){
//接收键盘输入
Scanner input=new Scanner(System.in);
while(input.hasNext()){
String str=input.nextLine();
//正则表达式对象
Pattern pattern=Pattern.compile("//b//w+//b");
//生成匹配器
Matcher matcher=pattern.matcher(str);
//记录单词数量
int wordsCount=0;
//遍历查找匹配,统计单词数量
while(matcher.find()){
wordsCount++;
}
System.out.println(str+"单词数:"+wordsCount);
}
}
准不准确,我们来看相同的输入所产生的结果:
Today is Monday
Today is Monday单词数:3
Today is Monday
Today is Monday单词数:3
Today is Monday?No!
Today is Monday?No!单词数:4
I'm Ok.
I'm Ok.单词数:3
每项的输出都是准确的,而且程序也不复杂,先生成一个正则表达式对象,然后使用匹配器进行匹配,之后通过一个while循环统计匹配的数量。需要说明的是,在Java的正则表达式中"/b"表示的是一个单词的边界,它是一个位置界定符,一边为字符或数字,另外一边则非字符或数字,例如"A"这样一个输入就有两个边界,即单词"A"的左右位置,这也就说明了为什么要加上"/w"(它表示的是字符或数字)。
正则表达式在字符串的查找、替换、剪切、复制、删除等方面有着非凡的作用,特别是面对大量的文本字符需要处理(如需要读取大量的LOG日志)时,使用正则表达式可以大幅地提高开发效率和系统性能,但是正则表达式是一个恶魔(Regular Expressions is evil),它会使程序难以读懂,想想看,写一个包含^、$、/A、/s、/Q、+、?、()、、{}等符号的正则表达式,然后告诉你这是一个“这样,这样……”的字符串查找,你是不是要崩溃了?这代码只有上帝才能看懂了!
注意 正则表达式是恶魔,威力巨大,但难以控制。