【问题标题】:Splitting a string using the empty string as the delimiter yields leading empty string but no trailing empty string [duplicate]使用空字符串作为分隔符拆分字符串会产生前导空字符串但没有尾随空字符串 [重复]
【发布时间】:2011-05-31 18:11:11
【问题描述】:

假设你在 Java 中有这个表达式:

"adam".split("")

这是告诉 Java 使用空字符串 ("") 作为分隔符来拆分 "adam"。这产生:

["", "a", "d", "a", "m"]

为什么 Java 在开头包含一个空字符串,而不是结尾?使用这个逻辑,结果不应该是:

["", "a", "d", "a", "m", ""]

【问题讨论】:

  • @marcog:哈哈,我害怕标题那个具有描述性。 ;) 但是,嘿,如果它有效的话。
  • 我倾向于错误地在标题中更具描述性。 :)
  • @marcog:我很想知道该标题是否保持了单词(“字符串”)出现次数最多的记录。 :)
  • 好吧,也许有点过分了。但是,我评论中的 +1 意味着至少 someone 喜欢它的描述性。 :)

标签: java regex split


【解决方案1】:

分隔符是一个正则表达式。正则表达式"" 匹配字符串的最开头(在adam 中的a 之前)。 docs 状态:

围绕匹配项拆分此字符串 给定的正则表达式。

因此,该方法将围绕a 之前的匹配进行拆分。文档还说:

这个方法就像通过调用 两参数拆分方法与 给定表达式和限制参数 为零。尾随空字符串是 因此不包括在 结果数组。

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

因此,虽然在字符串的末尾也会有匹配,但结果的尾随空字符串将被丢弃。因此,前导空字符串,但没有尾随空字符串。如果您想要尾随空字符串,只需传递一个负值作为第二个参数:

"adam".split("", -1);

这行得通,因为文档中的这个引用:

如果 n 为非正数,则模式 将被应用多次 可能的,数组可以有任何 长度。

要回答“为什么中间没有空字符串?”的问题,正则表达式将只返回字符串中每个位置的单个匹配项。因此,字符串中的两个连续字符之间不能有两个匹配项,所以回到我从文档中引用的第一个引号,这些额外的空字符串将不存在。

【讨论】:

  • 这背后有趣的是动机。尤其是 split("", 10) 最后仍会返回空字符串。
  • @Nikita 我猜一开始是偶然的,但后来他们不想破坏向后兼容性,所以引入了“如果 n 是非正数”部分。
  • 不,这不是意外;这种行为是故意从 Perl 的split 复制而来的。但是,Perl 会不会像 Java 那样在开头返回空标记。无论使用什么模式,或者指定什么块限制,目标字符串开头的零长度匹配都不会导致 Perl 的 split 中的前导标记为空。
  • @AlanMoore 你是说 Java 想复制 Pearl 的行为,但没有成功?
  • @didibus:没错。基本功能应该是一样的,但是他们把一些功能弄错了(比如前导空标记)并完全排除了其他功能,比如使用捕获组将分隔符(或其中的一部分)视为附加标记。 Perl split 的许多高级特性在 Java 中是不可能重现的,但我看不出它们为什么不能实现捕获的标记(正如我所说的那样)。在我看来,这是缺少的功能中最烦人的。
【解决方案2】:

查看 split 方法的 API 是这样的文本:“尾随的空字符串因此不包含在结果数组中。”

【讨论】:

  • “因此”一词表明应该引用更多上下文。
  • 很好的答案。太尴尬了,没看文档就被抓到了!
  • “此方法的工作方式就像通过使用给定表达式和零限制参数调用双参数拆分方法一样。因此,尾随的空字符串不包含在结果数组中。”并且“如果 n 为零,则该模式将被应用尽可能多的次数,数组可以具有任意长度,并且尾随的空字符串将被丢弃。”
  • @Adam Paynter 不用担心。当我第一次阅读你的问题时,我不确定。我很惊讶地看到它在 javadoc 中的说明。尽管我多次使用这种方法,但我从未注意到它。
  • 我们是否知道为什么 尾随 空字符串被丢弃,而前导 空字符串却不被丢弃?
【解决方案3】:

是的,但是在“a”和“d”、“d”和“a”、“a”和“m”之间有空字符串。而且它们也不会出现在返回的数组中。

split() 方法删除该空字符串的其他出现。

【讨论】:

  • 很公平。但是,如果它丢弃所有其他字符串,它为什么会选择保留第一个空字符串呢?这似乎是一个奇怪的决定。
  • 但是空字符串之间有空字符串吗?
  • 不,它不会删除其他出现的空字符串,只会删除尾随的。阅读我的答案以获得详细解释。
猜你喜欢
  • 1970-01-01
  • 2011-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-10
  • 2015-12-28
  • 1970-01-01
  • 2015-05-12
相关资源
最近更新 更多