.的行为String.split(这叫Pattern.split)Java 7和Java 8之间的更改。
文献资料
的文件比较Pattern.split在……里面Java 7和Java 8我们注意到增加了以下条款:当输入序列的开头有一个正宽度匹配时,则在结果数组的开头包含一个空的前导子字符串。但是,开头的零宽度匹配永远不会产生这样空的前导子字符串。
同样的子句也添加到String.split在……里面Java 8,与Java 7.
参考实施
让我们比较一下Pattern.split在Java 7和Java 8中引用内嵌。代码从grepcode检索,版本为7u40-B43和8-b132。
Java 7public String[] split(CharSequence input, int limit) {
int index = 0;
boolean matchLimited = limit > 0;
ArrayList matchList = new ArrayList<>();
Matcher m = matcher(input);
// Add segments before each match found
while(m.find()) {
if (!matchLimited || matchList.size()
String match = input.subSequence(index, m.start()).toString();
matchList.add(match);
index = m.end();
} else if (matchList.size() == limit - 1) { // last one
String match = input.subSequence(index,
input.length()).toString();
matchList.add(match);
index = m.end();
}
}
// If no match was found, return this
if (index == 0)
return new String[] {input.toString()};
// Add remaining segment
if (!matchLimited || matchList.size()
matchList.add(input.subSequence(index, input.length()).toString());
// Construct result
int resultSize = matchList.size();
if (limit == 0)
while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
resultSize--;
String[] result = new String[resultSize];
return matchList.subList(0, resultSize).toArray(result);}
Java 8public String[] split(CharSequence input, int limit) {
int index = 0;
boolean matchLimited = limit > 0;
ArrayList matchList = new ArrayList<>();
Matcher m = matcher(input);
// Add segments before each match found
while(m.find()) {
if (!matchLimited || matchList.size()
if (index == 0 && index == m.start() && m.start() == m.end()) {
// no empty leading substring included for zero-width match
// at the beginning of the input char sequence.
continue;
}
String match = input.subSequence(index, m.start()).toString();
matchList.add(match);
index = m.end();
} else if (matchList.size() == limit - 1) { // last one
String match = input.subSequence(index,
input.length()).toString();
matchList.add(match);
index = m.end();
}
}
// If no match was found, return this
if (index == 0)
return new String[] {input.toString()};
// Add remaining segment
if (!matchLimited || matchList.size()
matchList.add(input.subSequence(index, input.length()).toString());
// Construct result
int resultSize = matchList.size();
if (limit == 0)
while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
resultSize--;
String[] result = new String[resultSize];
return matchList.subList(0, resultSize).toArray(result);}
在Java 8中添加以下代码不包括输入字符串开头的零长度匹配,这说明了上面的行为。if (index == 0 && index == m.start() && m.start() == m.end()) {
// no empty leading substring included for zero-width match
// at the beginning of the input char sequence.
continue;
}
保持兼容性
Java 8及以上版本中的以下行为
使split跨版本的行为一致,并与Java 8中的行为兼容:如果你的裁判
能,会,可以匹配零长度字符串,只需添加
(?!\A)在…
终结,并将原始正则表达式包装在非捕获组中。
(?:...)(如有需要)。
如果你的裁判
不能匹配零长度字符串,你不需要做任何事情。
如果您不知道regex是否可以匹配零长度字符串,那么在步骤1中执行这两个操作。
(?!\A)检查字符串是否结束于字符串的开头,这意味着匹配是字符串开头的空匹配。
Java 7及更高版本中的以下行为
没有通用的解决方案split向后兼容Java 7和以前版本,但不能替换split指向您自己的自定义实现。