string中split的作用:分享最近在String.split方法上遇到的一个小坑
string中split的作用:分享最近在String.split方法上遇到的一个小坑(2)、字符串长度等于2,第一个字符必须时反斜杠\,并且第二个字符不是数字或字母(1)、字符串长度等于1,.$|()[{^?* \,并且字符串不是这里面中其中一个,也就是不是正则表达式的保留字符,使用这些字符串都要进行转义。调用spilt,默认调用了String内部的另一个重载方法,然后我猜想问题出在limit参数上面。接着往下面,调用的重载方法有两个不同的条件,分别走不同的方法。当传进来的regex满足下面两个条件之一就不当做正则表达式处理
最近在使用String类中的spilt方法对字符串进行分割的时候,在运行到下面取数组里面的元素的时候会出现StringIndexOutOfBoundsException
对此,请大家先看下面的代码
String str = "/1/2/3/4///"; String[] strs = str.split("/"); System.out.println("strs数组长度:" strs.length); System.out.println("strs数组元素:" Arrays.toString(strs));
对于这段代码,结果是:
strs数组长度:5 strs数组元素:[ 1 2 3 4]
为什么,有一个空字符串存在数组中呢,按照道理来说末尾的空字符串都默认去掉了,对此,只能找到jdk源码才能解决我的疑问了。
调用spilt,默认调用了String内部的另一个重载方法,然后我猜想问题出在limit参数上面。
接着往下面,调用的重载方法有两个不同的条件,分别走不同的方法。
当传进来的regex满足下面两个条件之一就不当做正则表达式处理
(1)、字符串长度等于1,.$|()[{^?* \,并且字符串不是这里面中其中一个,也就是不是正则表达式的保留字符,使用这些字符串都要进行转义。
(2)、字符串长度等于2,第一个字符必须时反斜杠\,并且第二个字符不是数字或字母
由于篇幅和时间有限,本文暂且只对目前的条件进行分析。
显然当前代码满足这个条件,继续进入if条件。
这个limit其实就是在限制分割的次数。
(1)、当limit == 0 时, limited 为false,!limited为true,默认不限制,取所有能分割的。代码走到2372就真相了,原来当limit == 0 时,默认从后往前去除为空的字符串。 if (limit == 0) { while (resultSize > 0 && list.get(resultSize - 1).length() == 0) { resultSize--; } } (2)、当limit == -1时,也是不做分割次数的限制,但是也不会去除list末尾的空字符串。所以上面代码修改后再次执行就是8了 修改代码后: String[] strs1 = str.split("/" -1); System.out.println("strs数组长度:" strs1.length); System.out.println("strs数组元素:" Arrays.toString(strs1)); 打印结果: strs数组长度:8 strs数组元素:[ 1 2 3 4 ] (3)、当limit >= 1时,分割次数受到限制,比如limit == 1时,不会分割字符串,直接返回原字符串,当等于2时,返回分割之后的2段字符串。同样允许末尾存在字符串 分类讨论及其验证如下: 1. limit == 1 代码: String[] strs2 = str.split("/" 1); System.out.println("strs数组长度:" strs2.length); System.out.println("strs数组元素:" Arrays.toString(strs2)); 结果: strs数组长度:1 strs数组元素:[/1/2/3/4///] 2. limit == 3 ( > 1 且 小于全部的分割次数) 代码: String[] strs3 = str.split("/" 3); System.out.println("strs数组长度:" strs3.length); System.out.println("strs数组元素:" Arrays.toString(strs3)); 结果: strs数组长度:3 strs数组元素:[ 1 2/3/4///] 3. limit == 100 (> 1 且 大于全部的分割次数) 代码: String[] strs4 = str.split("/" 100); System.out.println("strs数组长度:" strs4.length); System.out.println("strs数组元素:" Arrays.toString(strs4)); 结果: strs数组长度:8 strs数组元素:[ 1 2 3 4 ]
对此,对于我们常用的spilt还是存在一些陷阱,需要在编写代码的过程中对api有足够的理解深度。
如果文中有错误的地方,还请大家批评指正。