为什么在一个空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了这个(我怀疑它最初是一个“边缘案例”中的一个监督/错误),但现在已经不可撤销地融入了语言,所以它依然存在 。