Java String拆分删除了空值

时间:2013-01-30 10:43:12

标签: java string split

我正在尝试使用分隔符拆分Value。 但我发现了令人惊讶的结果

String data = "5|6|7||8|9||";
String[] split = data.split("\\|");
System.out.println(split.length);

我期待得到8个值。的 [5,6,7,EMPTY,8,9,空,空 但我只得到6个值。

任何想法以及如何解决。无论EMPTY值是否来自任何地方,它都应该在数组中。

6 个答案:

答案 0 :(得分:415)

默认情况下,

split(delimiter)会从结果数组中删除尾随的空字符串。要关闭此机制,我们需要使用split(delimiter, limit)的重载版本,limit设置为负值,如

String[] split = data.split("\\|", -1);

更多细节:
split(regex)在内部返回split(regex, 0)的结果,在此方法的documentation中,您可以找到(强调我的)

  

limit参数控制模式的应用次数,因此会影响结果数组的长度。

     

如果限制n 大于零,则模式最多应用n - 1次,数组的长度不大于n,并且数组的最后一个条目将包含除最后匹配分隔符之外的所有输入。

     

如果n 非正面,则模式将被应用尽可能多次,并且数组可以具有任意长度。

     

如果n ,则模式将被应用尽可能多次,数组可以具有任意长度,尾随空字符串将被丢弃

<强>异常

值得一提的是,只有当这样的空字符串由分裂机制创建时,删除尾随空字符串才有意义。因此对于"".split(anything),因为我们无法将""分开,所以我们将得到结果为[""]数组。
之所以发生这种情况是因为此处没有发生拆分,所以""尽管是空的并且尾随代表原始字符串,而不是通过拆分过程创建的空字符串。 / p>

答案 1 :(得分:31)

来自String.split(String regex)的文档:

  

此方法的工作方式就像调用带有给定表达式和limit参数为零的双参数split方法一样。 结尾的空字符串因此不包含在结果数组中。

因此,您必须使用带有负值的两个参数版本String.split(String regex, int limit)

String[] split = data.split("\\|",-1);

文档:

  

如果限制n大于零,那么模式将最多应用n - 1次,数组的长度将不大于n,并且数组的最后一个条目将包含超出最后匹配分隔符的所有输入。 如果n是非正数,则模式将被应用尽可能多次,并且数组可以具有任何长度。如果n为零,那么模式将被应用尽可能多次,数组可以具有任何长度,并且尾随空字符串将被丢弃。

这不会遗漏任何空元素,包括尾随元素。

答案 2 :(得分:4)

来自String.split() API Doc

  

围绕给定正则表达式的匹配拆分此字符串。   此方法的工作方式就像通过调用双参数split方法一样   给定的表达式和一个零的限制参数。尾随空   因此,字符串不包含在结果数组中。

重载String.split(regex, int)更适合您的情况。

答案 3 :(得分:3)

另一个选择是使用Guava的Splitter。它没有正则表达式的开销(在这种情况下你不需要),并且默认情况下不会丢弃空的尾随字符串。

例如:

 String data = "5|6|7||8|9||";
 Iterable<String> results = Splitter.on('|').split(data);
 // convert to array
 String[] asArray = Iterables.toArray(results, String.class);

有关详细信息,请参阅wiki: https://github.com/google/guava/wiki/StringsExplained

答案 4 :(得分:2)

String[] split = data.split("\\|",-1);

这不是所有时间的实际要求。上面的缺点如下所示:

Scenerio 1:
When all data are present:
    String data = "5|6|7||8|9|10|";
    String[] split = data.split("\\|");
    String[] splt = data.split("\\|",-1);
    System.out.println(split.length); //output: 7
    System.out.println(splt.length); //output: 8

缺少数据时:

Scenerio 2: Data Missing
    String data = "5|6|7||8|||";
    String[] split = data.split("\\|");
    String[] splt = data.split("\\|",-1);
    System.out.println(split.length); //output: 5
    System.out.println(splt.length); //output: 8

虽然缺少数据,但实际要求的长度应为7。因为有些情况比如我需要在数据库或其他东西中插入。我们可以通过使用以下方法来实现这一目标。

    String data = "5|6|7||8|||";
    String[] split = data.split("\\|");
    String[] splt = data.replaceAll("\\|$","").split("\\|",-1);
    System.out.println(split.length); //output: 5
    System.out.println(splt.length); //output:7

我在这里做的是,我正在删除“|”管道末端然后拆分字符串。如果您有“,”作为分隔符,那么您需要在replaceAll中添加“,$”。

答案 5 :(得分:1)

您可能有多个分隔符,包括空格字符,逗号,分号等。请使用[] +将可重复的字符分隔为一组,例如:

 String[] tokens = "a , b,  ,c; ;d,      ".split( "[,; \t\n\r]+" );

您将有4个令牌-a,b,c,d

在应用此拆分之前,需要删除源字符串中的前导分隔符。

作为所提问题的答案:

String data = "5|6|7||8|9||";
String[] split = data.split("[\\| \t\n\r]+");

添加了空格,以防万一,如果您将其与||

用作分隔符