今天在写一个统计用户信息的程序时出现了bug,导致统计结果与真实值有很大差距。经过仔细检查,我发现是错误地使用split函数导致的。看来还是对scala中的split函数的理解不够透彻。本篇博文将详细解释scala中String.split的参数及用法。
因为scala中的String复用了Java的String,因此这也是Java中String.split的用法。
split函数主要有两种参数形式:
def split(arg0: String): Array[String]
def split(arg0: String, arg1: Int): Array[String]
我们可以将第一种参数形式看作是默认arg1=0的第二种形式,即调用split(StrToSplit)等同于调用了split(StrToSplit, 0)。因此,我将主要介绍第二种参数形式。第二种参数形式中每个参数的意义如下:
arg0:String 是一个正则表达式,代表分割的边界。这个正则表达式成功匹配一次,split的结果中就会加入一个新的子串。子串包含上次匹配后(如果没有上次匹配就是被分割字符串的起始位置)到这次匹配前的所有字符。最后,split函数会将最后一次匹配后剩余的字串作为最后一个子串加入到结果中。
arg1: Int 是对分割后子串的个数的限定。理解这个参数才能正确的运用split函数。
当arg1大于0时,它限制arg0最多成功匹配arg1,1次,也就是说字符串最多被分成arg1个子串。此时split会保留分割出的空字符串(当两个arg0连续匹配活着arg0在头尾匹配,会产生空字符串),直到达到匹配上限。比如:
复制代码
1 scala> "a-b-c".split("-", 2)
2 res38: Array[String] = Array(a, b-c)
3
4 scala> "a-b-c".split("-", 4)
5 res39: Array[String] = Array(a, b, c)
6
7 scala> "-a-b-c--".split("-", 3)
8 res40: Array[String] = Array("", a, b-c--)
9
10 scala> "-a-b-c--".split("-", 6)
11 res41: Array[String] = Array("", a, b, c, "", "")
12
13 scala> "-a-b-c--".split("-", 5)
14 res42: Array[String] = Array("", a, b, c, -)
15
16 scala> "-a-b-c--".split("-", 8)
17 res43: Array[String] = Array("", a, b, c, "", "")
当arg1等于0时,split函数会尽可能多的匹配arg0,但不再保留处于末尾位置的空字符串(这里的一个特殊情况是,当被分割字符串是一个空字符串时,分割结果仍是一个空字符串组成的数组)。比如:
1 scala> "a-b-c".split("-", 0)
2 res48: Array[String] = Array(a, b, c)
3
4 scala> "a-b-c---".split("-", 0)
5 res49: Array[String] = Array(a, b, c)
6
7 scala> "-a--b--c---".split("-", 0)
8 res50: Array[String] = Array("", a, "", b, "", c)
9
10 scala> "".split("-", 0)
11 res51: Array[String] = Array("")
复制代码
当arg1小于0时,split函数会尽可能多的匹配arg0,并且保留末尾的空字符串。比如:
1 scala> "a-b-c".split("-", -1)
2 res52: Array[String] = Array(a, b, c)
3
4 scala> "-a--b--c-".split("-", -1)
5 res53: Array[String] = Array("", a, "", b, "", c, "")