我正在尝试拆分一个17字节的字符串,但是当我显示长度时它会显示18。
String s1 = "{{ (( 4 + 5 )) }}";
String[] s2 = s1.split("");
System.out.println("length = " + s2.length);
答案 0 :(得分:5)
它在Java 7中显示18
的长度,因为按空字符串分割将在每个字符之前和之后找到分隔符。
{ { ( (...
^ ^ ^ ^ ^
在Java 7中,trailing empty strings are discarded。
如果n为零,则模式将被应用尽可能多次,数组可以具有任何长度,并且尾随空字符串将被丢弃。
因此,在Java 7中,我得到18
的长度,因为尾随的空字符串被丢弃,但前导的空字符串不会被丢弃。
包括这一行
System.out.println(Arrays.toString(s2));
产生此输出
[, {, {, , (, (, , 4, , +, , 5, , ), ), , }, }]
带有前导空字符串。
但是,在Java 8中,this statement is now included in the Javadocs。
如果在此字符串的开头存在正宽度匹配,则在结果数组的开头包含空的前导子字符串。然而,开头的零宽度匹配从不会产生这样的空前导子串。
它不存在于Java 7 javadoc中。
看起来行为已被更改为消除零宽度匹配的前导字符串,就是这个问题的情况。
Java 8输出:
[{, {, , (, (, , 4, , +, , 5, , ), ), , }, }]
,
数组打印后的开始[
现已消失,长度现为17
。
答案 1 :(得分:4)
看起来您正在使用Java 7。
在Java 8之前"foo".split("")
拆分每个空字符串,但由于空字符串存在于每个字符之前和之后,我们在这些地方(标有|
)|f|o|o|
有效地分割,产生于第一个数组如["", "f","o","o",""]
。
现在,由于split
还删除了空尾随字符串"foo".split("")
,因此返回此数组["", "f","o","o"]
,如您所见,它在开始时有一个空字符串。
你可以通过拆分不在字符串开头的地方来解决这个问题。您可以使用正则表达式使用正则表达式split("(?<!^)")
使用负面观察(?<!...)
,它使用^
表示的字符串的开头。
String[] s2 = s1.split("(?<!^)"); //for "foo" this split returns ["f","o","o"]
其他人无法重现您的问题,因为此行为在Java 8中发生了变化:Why in Java 8 split sometimes removes empty strings at start of result array?