您的位置:首页 > 编程语言 > Java开发

共同学习Java源码--常用数据类型--String(十四)

2016-04-10 11:40 501 查看
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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: