349

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

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 值来自任何地方,它都应该在数组中。

4

5 回答 5

589

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

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

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

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

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

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

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

例外

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

于 2013-01-30T10:44:28.183 回答
38

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

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

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

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

文件:

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

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

于 2013-01-30T10:47:32.300 回答
7

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 中添加 ",$"。

于 2018-06-09T05:48:24.193 回答
5

来自String.split() API 文档

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

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

于 2013-01-30T10:44:36.537 回答
2

您可能有多个分隔符,包括空格字符、逗号、分号等。使用 []+ 将它们放在可重复的组中,例如:

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

添加空格以防万一您将它们作为分隔符与 |

于 2019-04-16T05:26:10.593 回答