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

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

我期望得到8个值。(5、6、7,空的,8,9,空的,空) 但我只得到6个值。

任何想法以及如何修复。无论EMPTY值出现在任何位置,它都应该在数组中。


当前回答

来自String的文档。分割(字符串正则表达式):

该方法的工作原理就像使用给定表达式和限制参数为0调用双参数split方法一样。因此,尾随的空字符串不包括在结果数组中。

所以你必须使用两个参数version String。split(String regex, int limit)带负值:

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

Doc:

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

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

其他回答

Split(分隔符)默认情况下从结果数组中移除尾随的空字符串。要关闭这种机制,我们需要使用split(分隔符,limit)的重载版本,并将limit设置为负值

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

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

The limit parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array's length will be no greater than n, and the array's last entry will contain all input beyond the last matched delimiter. If n is non-positive then the pattern will be applied as many times as possible and the array can have any length. If n is zero then the pattern will be applied as many times as possible, the array can have any length, and trailing empty strings will be discarded.

例外:

值得一提的是,只有当这些空字符串是由拆分机制创建时,删除尾随的空字符串才有意义。因此对于"".split(任何东西),由于我们不能将""进一步拆分,我们将得到result[""]数组。 之所以会发生,是因为这里没有发生分裂,所以""尽管是空的,并且拖尾代表原始字符串,而不是由分裂过程创建的空字符串。

从String.split() API文档:

围绕给定正则表达式的匹配来拆分此字符串。 该方法的工作原理就像调用带有两个参数的split方法一样 给定的表达式和一个极限参数为0。落后于空 因此,结果数组中不包括字符串。

重载字符串。Split (regex, int)更适合你的情况。

来自String的文档。分割(字符串正则表达式):

该方法的工作原理就像使用给定表达式和限制参数为0调用双参数split方法一样。因此,尾随的空字符串不包括在结果数组中。

所以你必须使用两个参数version String。split(String regex, int limit)带负值:

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

Doc:

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

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

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

你可以有多个分隔符,包括空格字符,逗号,分号等,把那些可重复的组与[]+,像:

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

如果您将这些作为分隔符和|,则添加空格以防万一