共同学习Java源码--常用数据类型--String(十四)
public String[] split(String regex, int limit) {
/* fastpath if the regex is a (1)one-char String and this character is not one of the RegEx's meta characters ".$|()[{^?*+\\", or (2)two-char String and the first char is the backslash and the second is not the ascii digit or ascii letter. */
char ch = 0;
if (((regex.value.length == 1 &&
".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
(regex.length() == 2 &&
regex.charAt(0) == '\\' &&
(((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
((ch-'a')|('z'-ch)) < 0 &&
((ch-'A')|('Z'-ch)) < 0)) &&
(ch < Character.MIN_HIGH_SURROGATE ||
ch > Character.MAX_LOW_SURROGATE))
{
int off = 0;
int next = 0;
boolean limited = limit > 0;
ArrayList<String> list = new ArrayList<>();
while ((next = indexOf(ch, off)) != -1) {
if (!limited || list.size() < limit - 1) {
list.add(substring(off, next));
off = next + 1;
} else { // last one //assert (list.size() == limit - 1); list.add(substring(off, value.length));
off = value.length;
break;
}
}
// If no match was found, return this if (off == 0)
return new String[]{this};
// Add remaining segment if (!limited || list.size() < limit)
list.add(substring(off, value.length));
// Construct result int resultSize = list.size();
if (limit == 0) {
while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
resultSize--;
}
}
String[] result = new String[resultSize];
return list.subList(0, resultSize).toArray(result);
}
return Pattern.compile(regex).split(this, limit);
}
public String[] split(String regex) {
return split(regex, 0);
}
这两个方法一起看,是将本字符串以正则表达式为规则,将字符串内容打散成数组的方法。
第一个方法首先定义char变量ch初始值为0,然后进入一个很复杂的if表达式,其实把格式整理好了就容易看了。
if (
(
(regex.value.length == 1 && ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1)
||
(
regex.length() == 2 && regex.charAt(0) == '\\'
&& (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0
&& ((ch-'a')|('z'-ch)) < 0
&& ((ch-'A')|('Z'-ch)) < 0
)
)
&&
(ch < Character.MIN_HIGH_SURROGATE || ch > Character.MAX_LOW_SURROGATE)
)
先看最下方那个&& 右边是判断ch在D800和DFFF之间。
最下方那个&&左边是一个||连接的两个表达式。
||左边是判断regex变量长度为1,且不含正则表达式基本元素(.$|()[{^?),说白了就是判断是一个字符且不是正则表达式。
||右边是在判断regex变量长度为2,且第一个字符是”\”,也就是转义字符。后面是用|来判断regex不属于0-9A-Za-z这个区间的字符,|是判断二进制里每一位只要有一个是1,那么最后结果的二进制相应位就是1。
这个if判断的是非正则表达式,如果regex为正则表达式,直接调用Pattern类的方法来处理,此处不做详谈。
然后定义变量off,初始值为0,也就是搜索的初始下标。定义变量next也就是每个regex里。
定义一个ArrayList。
进入while循环,在本字符串里不停地搜索ch的下标,只要ch的下标不是-1。ch此时可能是原来regex的第一个或第二个字符。
如果是从第二个方法调用的,那么limit是0,limited就是false,off初始值是0。进入if中将off到这个元素下标位置的所有元素截取成新字符串加入到list中,不断往复,off会移动到next下标的右侧。
如果limit不为0且limit-1大于等于ArrayList的长度,那么进入else中,这里就截取off之后的所有字符串放入list中。else的成立条件推测是limit要大于0。
跳出循环后off还是0.说明没有搜索到,直接返回本字符串,将本字符串放入一个String数组中。
接下来是将off的最后取值之后的元素放入list中。然后获取这个ArrayList的长度,接下来处理的是ArrayList最后一个元素是不是空字符串,如果是,则记录ArrayList长度的变量resultSize减一,其实这种方式法去掉结果中间的空串。
最后构建字符串数组,用list的相关方法生成数组返回。
第二个方法就是调用第一个方法,并将limit传入0。
原文地址: https://zhuanlan.zhihu.com/p/46622167
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
相关文章