为什么在一个空string上“分裂”返回一个非空数组?

在空string上拆分将返回大小为1的数组:

scala> "".split(',') res1: Array[String] = Array("") 

考虑到这将返回空数组:

 scala> ",,,,".split(',') res2: Array[String] = Array() 

请解释 :)

出于同样的原因

 ",test" split ',' 

 ",test," split ',' 

将返回大小为2的数组。第一个匹配之前的所有内容将作为第一个元素返回。

如果你把一个橙子分成零次,那你就有一块 – 橘子。

分割一个空string将返回空string作为第一个元素。 如果在目标string中找不到分隔符,那么即使它是空的,您也将得到一个保存原始string的大小为1的数组。

"a".split(",") – > "a"因此"".split(",") – > ""

Java和Scala拆分方法分两步操作:

  • 首先,用分隔符分割string。 自然的结果是,如果string不包含分隔符,则返回仅包含string的数组。
  • 其次, 删除所有最右边的空string。 这是",,,".split(",")的原因",,,".split(",")返回空数组。

据此, "".split(",")应该是一个空数组,因为第二步,对吧?

这应该。 不幸的是,这是一个人为的angular落案例。 这很糟糕,但至less在java.util.regex.Pattern 有logging ,如果你还记得看看这个文档:

对于n == 0,结果是n <0,除了尾部的空string不会被返回。 (注意,input本身是一个空string的情况是特殊的,如上所述,并且极限参数不适用于此)。

所以,我build议你总是传递n == -1作为第二个参数(这将跳过上面的第二步),除非你明确地知道你想达到什么目的/你确定空string不是你的程序得到一个input。

TL; DR:拆分空string是人为引入的angular落案例,文档会提醒您。 总是传递-1作为第二个参数,以避免错误,除非你有一个很好的理由。

在所有编程语言中,我知道一个空string仍然是一个有效的string。 因此,使用任何分隔符进行分割将始终返回单个元素数组,其中该元素是空string。 如果它是一个空(不是空白)string那么这将是一个不同的问题。

这种split行为是从Javainheritance的,好或坏…
Scala不重写String原语的定义。

请注意,您可以使用limit参数来修改行为 :

limit参数控制模式应用的次数,因此影响结果数组的长度。 如果极限值n大于零,那么模式将被最多应用n-1次,数组的长度将不会大于n,并且数组的最后一项将包含超出最后匹配分隔符的所有input。 如果n是非正值,那么该模式将被应用尽可能多次,并且该数组可以具有任何长度。 如果n为零,则模式将尽可能多次应用,数组可以有任意长度,尾随的空string将被丢弃。

即你可以设置limit=-1来得到(all?)其他语言的行为:

 @ ",a,,b,,".split(",") res1: Array[String] = Array("", "a", "", "b") @ ",a,,b,,".split(",", -1) // limit=-1 res2: Array[String] = Array("", "a", "", "b", "", "") 

这似乎是众所周知的Java的行为是相当混乱,但:

上面的行为可以从Java 5至Java 8中观察到。

试图在JDK-6559590中拆分空string时将行为更改为返回空数组。 但是,当JDK-8028321在不同的地方引起回归时,它很快就被恢复了。 这个改变永远不会成为最初的Java 8版本。

注意:split方法从一开始就不是Java( 不在1.0.2中 ),实际上从1.4开始(例如,见2002年的JSR51 )。 我仍在调查…

不清楚的是,为什么Java首先select了这个(我怀疑它最初是一个“边缘案例”中的一个监督/错误),但现在已经不可撤销地融入了语言,所以它依然存在 。