劉華煜 蔣維
摘要:如何把縮寫的班級字符串分拆成單獨的班級是一件麻煩事。用正則表達式能很好地解決這個問題。
關鍵詞:正則表達式;golang
中圖分類號:TP391.1 文獻標識碼:A
文章編號:1009-3044(2019)35-0223-01
在處理學校班級相關事情時,經常會碰到“2015級應用數學一、三班、統計數學班、2016級專升本班”這種縮寫表述方式。首先是省略年級,如例子中的“統計數學班”,那么年級就會是剛剛出現的年級,即“2015級”。其次專業可能會分班,如“2015級應用數學一、三班”,實際上是“2015級應用數學一班、2015級應用數學三班”的縮寫。那么現在的問題就是如何將這種表述分拆成一個一個獨立的班級,如把上面的例子拆成“2015級應用數學一班、2015級應用數學三班、2015級統計數學班、2016級專升本班”。
首先可以直接用字符串解析的方法來解決這個問題,但其思路煩瑣,還容易出錯。而用正則表達式就沒有這些問題。
幾乎所有的現代編程語言都支持正則表達式,由于我在處理學校班級相關事情時用的是golang,所以以下論述均以gol-ang為背景。
1 正則表達式的構建
對于我們這個問題,正則表達式應該是:
^(20..級)([^、]*)((中文數字)(、(中文數字))*)?班((、(20..級)?[^、]*((中文數字)(、(中文數字))*)?班)*)$
其中中文數字=一|二|三|四|五|六|七|八|九|十。
由于第一個班級必須有年級,后面的則可以省略,所以第一個(20..級)后沒有問號,第二個(20..級)后面則有一個問號。[^、]*是專業名稱,((中文數字)(、(中文數字))*)是班級序號,由于專業不一定會分班,所以班級序號后有一個問號。
2 年級、專業和班級序號的提取
對“(、(20..級)?[^、]*((中文數字)(、(中文數字))*)?班)*”而言,golang只能提取出最后一個匹配項,這是無法滿足問題需求的。為了解決這個問題,我們需要先提取“((、(20..級)?[^、]*((中文數字)、((中文數字))*)?班)*)”,即所有匹配項的集合,再對所有匹配項的集合繼續應用正則表達式“^、(20..級)?([^、]*)((%s)(、(%s))*)?班((、(20..級)?[^、]*((%s)(、(%s))*)?班)*)$”,提取出第一項,然后再用這個正則表達式提取出第二項,……,直到剩下的字符串為空字符串。
對于“((中文數字)(、(中文數字))*)”,就不用這么麻煩了,因為其只涉及班級序號,所以用strings.Split函數就行了。
3 代碼
函數ParseClasses的參數是縮寫班級字符串,返回值是一個切片,切片的每個元素都是一個完整的班級字符串。
func ParseClasses(str string)[]string{
var reg1, reg2 *regexp.Regexp
tmp:="一|二|三|四|五|六|七|八|九|十"
s1:="(20..級)([^、]*)((%s)(、(%s))*)?班((、(20..級)?[^、]*((%s)(、(%s))*)?班)*)$、
ss1:= fmt.Sprintf(sl, tmp, tmp, tmp, tmp)
s2:=`^、(20..級)?([^、]*)((%s)(、(%s))*)?班((、(20..級)?[^、]*((%s)(、(%s))*)?班)*)$、
ss2:=fmt.Sprintf(s2, tmp, tmp, tmp, tmp)
reg1=regexp.MustCompile(ss1)
reg2=regexp.MustCompile(ss2)
var classes []string
result:=reg1.FindStringSubmatch(str)
remainder:=result[7]
nowji:=result[1]
nums:=strings.Split(result[3],"、")
for_,e:=range nums{
classes=append(classes,nowji+result[2]+e+"班")
}
for remainder!=}"{
r:=reg2.FindStringSubmatch(remainder)
if r[1]!=""{
nowji=r[1]
}
remainder=r[7]
nums=strings.Split(r[3],"、")
for_,e:=range nums{
classes=append(classes, nowji+r[2]+e+"班")
}
}
return classes
}
4 結束語
正則表達式技術可以優雅的解析縮寫班級字符串。我這里給出的方案暫時無法處理班級序號大于十的情況,不過把方案略作修改即可達到目的。由于幾乎碰不到序號大于十的班級,所以為了程序簡潔,我這里只給出班級序號不大于十的解決方案。
參考文獻:
[1]Ben Forta.正則表達式必知必會[M].北京:人民郵電出版社,2007.
[2]Matt Butcher. Go語言實戰[M].北京:機械工業出版社,2019.
【通聯編輯:謝媛媛】
收稿日期:2019-10-19
作者簡介:劉華煜(1976-),男,洛陽師范學院教師,主要研究方向為計算機軟件開發及應用;蔣維(1981-),女,洛陽師范學院教師,千要研究方向為計算機應用與技術。