【问题标题】:Confusions with String's split method与 String 的 split 方法混淆
【发布时间】:2014-07-11 16:24:42
【问题描述】:

我已经通过String's split method documentation,但结果并不如预期。当我们拆分一个将 limit 参数设置为负值的字符串时,它总是附加一个空值。为什么要这样做?考虑一些情况

// Case 1
String str = "1#2#3#";
System.out.println(str.split("#").length); // Prints 3
System.out.println(str.split("#", -1).length); // Prints 4

我在这里期望的是两个打印件 3。

// Case 2
str = "";
System.out.println(str.split("#").length); // Prints 1
System.out.println(str.split("#", -1).length); // Prints 1

现在由于没有找到匹配项,通常的无限制拆分方法应该打印 0,但它会创建一个包含空字符串的数组。

// Case 3
str = "#";
System.out.println(str.split("#").length); // Prints 0
System.out.println(str.split("#", -1).length); // Prints 2

现在我有一个匹配项,并且没有限制参数的拆分方法可以正常工作。这是我的预期输出,但为什么它不会像案例 2 那样在这种情况下创建一个空数组?

// Case 4
str = "###";
System.out.println(str.split("#").length); // Prints 0
System.out.println(str.split("#", -1).length); // Prints 4

这里第一个拆分方法符合预期,但为什么第二个给出 4 而不是 3?

// Case 5
str = "1#2#3#";
System.out.println(str.split("#", 0).length); // Prints 3
System.out.println(str.split("#", 3).length); // Prints 3
System.out.println(str.split("#", 4).length); // Prints 4

现在是正数限制的最后一个案例。如果正数

【问题讨论】:

    标签: java regex string split


    【解决方案1】:

    来自JavaDoc for String

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

    强调我的。

    在负限制情况下,空匹配不会被丢弃,所以如果我用E 表示空匹配:

    1#2#3# -> 1 # 2 # 3 # E
    E      -> E
    #      -> E # E
    ###    -> E # E # E # E
    

    在您的最后一个示例中(具有正限制),只有在 n == 0 时才会丢弃空的尾随空格。

    【讨论】:

    • 如果仅在 n==0 时丢弃空尾随,那么在情况 5 中,当我将 n 设为 3 时,为什么它不包含空尾随。但是当我将 n 设为 4 时,它包含了空的尾随。
    • 并且数组的最后一个条目将包含最后一个匹配分隔符之外的所有输入 您无法将空字符串视为字符串。当您输入 4 时,它匹配 3 次,然后附加空字符串。当你放 3 时,它匹配两次,然后放其余的(恰好是另一个匹配)
    • @SyamS 在第 5 种情况下,有 恰好 3 个匹配项可供使用,因此 03 给出相同的结果,3 是数量的限制结果。 4 匹配可用的 3 然后将剩余的字符串附加到输出 - 空字符串。
    【解决方案2】:

    混淆的主要来源是文档中经常遗漏的部分:

    ... 如果 n 为 0 则 ...,并且 尾随的空字符串将被丢弃

    一旦你明白了一切都是有意义的。

    【讨论】:

    • @SyamS - 这在别处有所介绍...如果表达式与输入的任何部分都不匹配,则结果数组只有一个元素,即这个字符串。
    【解决方案3】:

    来自documentation

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

    似乎否定的limit 行为被预定义为最大化匹配,并在最后存储任何其他内容。

    【讨论】:

    • 同意,但考虑案例 3,该模式可以应用 3 次,为什么要添加一个额外的空字符串以使数组长度为 4?
    • 在案例 4 中有 4 个字符串(全部为空)。(before)#(middle1)#(middle2)#(after) 该数组构建了 3 个匹配项(空字符串 3 次),然后 "Everything在最后一场比赛之后”(另一个空字符串)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-27
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 2014-04-15
    • 1970-01-01
    相关资源
    最近更新 更多