拆分字符串显示更多字符

时间:2015-02-12 19:30:36

标签: java

我正在尝试拆分一个17字节的字符串,但是当我显示长度时它会显示18。

String s1 = "{{ (( 4 + 5 )) }}";
String[] s2 = s1.split("");
System.out.println("length = " + s2.length);

enter image description here

2 个答案:

答案 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。

enter image description here

在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?