Java字符串拆分删除空值


286

我试图使用分隔符拆分值。但是我发现了令人惊讶的结果

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

我期望得到8个值。[5,6,7,EMPTY,8,9,EMPTY,EMPTY] 但是我只得到6个值。

任何想法和解决方法。无论EMPTY值在何处,它都应该位于数组中。

Answers:


491

split(delimiter)默认情况下,从结果数组中删除结尾的空字符串。要关闭此机制,我们需要使用重载版本的split(delimiter, limit)并将其limit设置为负值,例如

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

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

limit参数控制应用图案的次数,因此会影响所得数组的长度。

如果限制n大于零,则该模式将最多n应用- 1次,数组的长度将不会大于n,并且数组的最后项将包含超出最后匹配的定界符的所有输入。

如果n的非正则模式将被应用多次可能的,并且阵列可以具有任意长度。

如果nIS 则模式将被应用的次数成为可能,该阵列可具有任何长度,并且拖尾空字符串将被丢弃

例外情况

值得一提的是,只有在拆分机制创建了这种空字符串的情况下,删除尾随的空字符串才有意义。因此,"".split(anything)因为我们不能""进一步分割,所以将得到结果[""]数组。
发生这种情况是因为此处未发生拆分,因此""尽管为空,但尾随表示原始字符串,而不是拆分过程创建的空字符串。


2
哇。表现出色。但是-1如何改变一切?
Reddy 2013年

1
您甚至可以尝试data.split("\\|", 8)
Subhrajyoti Majumder 2013年

23
不要使用,split("\\|", 8)因为这限制了前八个令牌!如果您的字符串是可变的,则应使用split("\\|", -1)它,以便它创建无限数量的令牌,并且最后不丢弃空令牌。
ADTC 2013年

2
@Reddy -1(或任何负数,实际上不管绝对值是多少)都告诉split方法将空令牌保留在最后。默认值为0,它告诉方法在数组末尾丢弃空令牌。
ADTC 2013年

8
显然,很多人期望保留尾随空字符串是的默认功能split(regex)。他们最后来到这里,发现事实并非如此。
阿提拉(Attila Tanyi)

32

从以下文档中String.split(String regex)

该方法的工作方式就像通过调用具有给定表达式且限制参数为零的二参数拆分方法。因此,结尾的空字符串不包括在结果数组中。

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

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

文件:

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

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



4

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内添加“,$”。


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]+");

添加空白,以防万一,如果您将它们与|一起作为分隔符

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.