今天在寫一個統計用戶信息的程序時出現了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)。所以,我將主要介紹第二種參數形式。第二種參數形式中每一個參數的意義以下:es5
arg0: String 是一個正則表達式,表明分割的邊界。這個正則表達式成功匹配一次,split的結果中就會加入一個新的子串。子串包含上次匹配後(若是沒有上次匹配就是被分割字符串的起始位置)到此次匹配前的全部字符。最後,split函數會將最後一次匹配後剩餘的字串做爲最後一個子串加入到結果中。spa
arg1: Int 是對分割後子串的個數的限定。理解這個參數才能正確的運用split函數。scala
當arg1大於0時,它限制arg0最多成功匹配arg1-1次,也就是說字符串最多被分紅arg1個子串。此時split會保留分割出的空字符串(當兩個arg0連續匹配活着arg0在頭尾匹配,會產生空字符串),直到達到匹配上限。好比:
code
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,但再也不保留處於末尾位置的空字符串(這裏的一個特殊狀況是,當被分割字符串是一個空字符串時,分割結果還是一個空字符串組成的數組)。好比:blog
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, "")