JAVA中字符串的split方法有两个陷阱需要注意
在开发过程中,我们会碰到一种场景,需要对字符串进行分割,从而得到更具体的信息。
比如下面这个字符串:
String str = "123455#JAVA编程思想#这是一本JAVA圣经级别的书籍!";
该字符串包含书籍ID、书籍名称以及简介,三条信息用#
号连接在一起。
想要得到这三条信息,我们通常使用split
方法:
String[] strArray = str.split("#");
for (int i = 0; i < strArray.length; i++) {
System.out.println(strArray[0]);// 书籍ID
System.out.println(strArray[1]);// 书籍名称
System.out.println(strArray[2]);// 简介
}
split
使用很简单,但一不小心,很容易掉进两个陷阱:
split的参数是正则表达式,不是字符串对象
当大家看到str.split("#")
时,很容易误解#
是一个字符串对象,实际上JDK中 split
方法定义的是正则表达式。
所以当要分割的字符串是正则表达式中的特殊符号时,执行split
方法就不会得到预期的结果。
比如分隔符由#
变为 |
:
String str = "123455|JAVA编程思想|这是一本JAVA圣经级别的书籍!";
String[] strArray = str.split("|");
for (int i = 0; i < strArray.length; i++) {
System.out.println(i + " >> " + strArray[i]);
}
执行结果是:
0 >> 1
1 >> 2
2 >> 3
3 >> 4
4 >> 5
5 >> 5
6 >> |
7 >> J
8 >> A
9 >> V
10 >> A
11 >> 编
12 >> 程
13 >> 思
14 >> 想
15 >> |
16 >> 这
17 >> 是
18 >> 一
19 >> 本
20 >> J
21 >> A
22 >> V
23 >> A
24 >> 圣
25 >> 经
26 >> 级
27 >> 别
28 >> 的
29 >> 书
30 >> 籍
31 >> !
要解决这个问题,有两种方法:
1、对特殊字符做转义
正则表达式中转义是\
,所以split的参数应该是\|
,然而\
在JAVA中也是转义字符,即也是特殊字符,也需要转移,所以最终split的参数是\\|
。
修改后的代码就是:
String str = "123455|JAVA编程思想|这是一本JAVA圣经级别的书籍!";
String[] strArray = str.split("\\|");
for (int i = 0; i < strArray.length; i++) {
System.out.println(i + " >> " + strArray[i]);
}
2、将特殊字符放在中括号中
正则表达式中,中括号是用来定义匹配的字符范围。
修改后的代码是:
String str = "123455|JAVA编程思想|这是一本JAVA圣经级别的书籍!";
String[] strArray = str.split("[|]");
for (int i = 0; i < strArray.length; i++) {
System.out.println(i + " >> " + strArray[i]);
}
使用split方法时,有的特殊字符需要注意,那哪些字符需要特别关注呢?
正则表达式中有11个特殊字符:^
、$
、|
、.
、*
、+
、?
、()
、{}
、\
、/
除了/
之外,直接用其他特殊字符分割字符串,都不会得到预期的结果。
甚至在使用*
、+
、?
、{}
作为分割字符串时,编译就报错,强制我们去做转义。
为了保证split分割的结果是正确的,也为了减少记忆特殊字符串的麻烦,我建议大家在使用split时,就将分割字符串放在中括号中。即使用第二种方式:
String[] strArray = str.split("[|]");
split分割后的数组长度可能小于预期的长度
对字符串进行分割后,我们可能会将这些信息赋值给一个对象,比如:
String str = "123455#JAVA编程思想#这是一本JAVA圣经级别的书籍!";
String[] strArray = str.split("[#]");
Book book = new Book();
book.setId(strArray[0]);
book.setName(strArray[1]);
book.setDesc(strArray[2]);
一般情况下这是没有问题的,但是如果分割的字符串最后没有书籍简介,就会出问题:
String str = "123455#JAVA编程思想#";
String[] strArray = str.split("[#]");
for (int i = 0; i < strArray.length; i++) {
System.out.println(i + " >> " + strArray[i]);
}
执行代码的结果是:
0 >> 123455
1 >> JAVA编程思想
也就是分割后的数组长度是2,而我们预期的长度是3,所以执行book.setDesc(strArray[2])
代码就会报错。
如果想让上面的字符串分割后的数组长度为3,应该怎么处理?split方法中提供了第二个参数:
String str = "123455#JAVA编程思想#";
String[] strArray = str.split("[#]", 3);
for (int i = 0; i < strArray.length; i++) {
System.out.println(i + " >> " + strArray[i]);
}
执行代码的结果是:
0 >> 123455
1 >> JAVA编程思想
2 >>
查看JDK的源码,可以发现split只传一个参数时,实际上第二个参数默认传的是0。
当第二个参数limit
的值大于0时,表示将字符串分割为几段(也就是数组长度),但这个长度也不能大于字符串中分割字符串的个数+1。
String str = "a##b#";
String[] arr1 = str.split("[#]", 2);
/**
分割后的数组为:
arr1[0] = "a";
arr1[1] = "#b#";
*/
String[] arr2 = str.split("[#]", 3);
/**
分割后的数组为:
arr2[0] = "a";
arr2[1] = "";
arr2[2] = "b#";
*/
String[] arr3 = str.split("[#]", 4);
/**
分割后的数组为:
arr3[0] = "a";
arr3[1] = "";
arr3[2] = "b";
arr3[3] = "";
*/
String[] arr4 = str.split("[#]", 5);
/**
字符串中的#有3个,最多能分割成长度为4的数组,所以第二个参数传5时,结果和传4是一样的:
arr4[0] = "a";
arr4[1] = "";
arr4[2] = "b";
arr4[3] = "";
*/
当第二个参数limit
的值小于0时,结果就有些出人意料了,得到的数组是完全按照指定字符分割的。
String str = "a##b#";
String[] arr1 = str.split("[#]", -1);
/**
分割后的数组为:
arr1[0] = "a";
arr1[1] = "";
arr1[2] = "b";
arr1[3] = "";
*/
总结
1、在使用split对字符串进行分割时,将分隔符放在中括号中。str.split("[|]")
2、当要通过数组游标获取分割后的信息时,split第二个参数传入一个负值。str.split('[|]', -1)
注意到这两点,你在使用split方法时就绝对不会出错啦!
看到这里,你是否应该马上搜索代码,看看split的使用都正确了?如果没有,立即改正吧!
ps:
如果文章对你有帮助,请关注我的公众号吧!