劉華煜 蔣維
摘要:如何把縮寫的班級字符串分拆成單獨(dú)的班級是一件麻煩事。用正則表達(dá)式能很好地解決這個問題。
關(guān)鍵詞:正則表達(dá)式;golang
中圖分類號:TP391.1 文獻(xiàn)標(biāo)識碼:A
文章編號:1009-3044(2019)35-0223-01
在處理學(xué)校班級相關(guān)事情時,經(jīng)常會碰到“2015級應(yīng)用數(shù)學(xué)一、三班、統(tǒng)計(jì)數(shù)學(xué)班、2016級專升本班”這種縮寫表述方式。首先是省略年級,如例子中的“統(tǒng)計(jì)數(shù)學(xué)班”,那么年級就會是剛剛出現(xiàn)的年級,即“2015級”。其次專業(yè)可能會分班,如“2015級應(yīng)用數(shù)學(xué)一、三班”,實(shí)際上是“2015級應(yīng)用數(shù)學(xué)一班、2015級應(yīng)用數(shù)學(xué)三班”的縮寫。那么現(xiàn)在的問題就是如何將這種表述分拆成一個一個獨(dú)立的班級,如把上面的例子拆成“2015級應(yīng)用數(shù)學(xué)一班、2015級應(yīng)用數(shù)學(xué)三班、2015級統(tǒng)計(jì)數(shù)學(xué)班、2016級專升本班”。
首先可以直接用字符串解析的方法來解決這個問題,但其思路煩瑣,還容易出錯。而用正則表達(dá)式就沒有這些問題。
幾乎所有的現(xiàn)代編程語言都支持正則表達(dá)式,由于我在處理學(xué)校班級相關(guān)事情時用的是golang,所以以下論述均以gol-ang為背景。
1 正則表達(dá)式的構(gòu)建
對于我們這個問題,正則表達(dá)式應(yīng)該是:
^(20..級)([^、]*)((中文數(shù)字)(、(中文數(shù)字))*)?班((、(20..級)?[^、]*((中文數(shù)字)(、(中文數(shù)字))*)?班)*)$
其中中文數(shù)字=一|二|三|四|五|六|七|八|九|十。
由于第一個班級必須有年級,后面的則可以省略,所以第一個(20..級)后沒有問號,第二個(20..級)后面則有一個問號。[^、]*是專業(yè)名稱,((中文數(shù)字)(、(中文數(shù)字))*)是班級序號,由于專業(yè)不一定會分班,所以班級序號后有一個問號。
2 年級、專業(yè)和班級序號的提取
對“(、(20..級)?[^、]*((中文數(shù)字)(、(中文數(shù)字))*)?班)*”而言,golang只能提取出最后一個匹配項(xiàng),這是無法滿足問題需求的。為了解決這個問題,我們需要先提取“((、(20..級)?[^、]*((中文數(shù)字)、((中文數(shù)字))*)?班)*)”,即所有匹配項(xiàng)的集合,再對所有匹配項(xiàng)的集合繼續(xù)應(yīng)用正則表達(dá)式“^、(20..級)?([^、]*)((%s)(、(%s))*)?班((、(20..級)?[^、]*((%s)(、(%s))*)?班)*)$”,提取出第一項(xiàng),然后再用這個正則表達(dá)式提取出第二項(xiàng),……,直到剩下的字符串為空字符串。
對于“((中文數(shù)字)(、(中文數(shù)字))*)”,就不用這么麻煩了,因?yàn)槠渲簧婕鞍嗉壭蛱枺杂胹trings.Split函數(shù)就行了。
3 代碼
函數(shù)ParseClasses的參數(shù)是縮寫班級字符串,返回值是一個切片,切片的每個元素都是一個完整的班級字符串。
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 結(jié)束語
正則表達(dá)式技術(shù)可以優(yōu)雅的解析縮寫班級字符串。我這里給出的方案暫時無法處理班級序號大于十的情況,不過把方案略作修改即可達(dá)到目的。由于幾乎碰不到序號大于十的班級,所以為了程序簡潔,我這里只給出班級序號不大于十的解決方案。
參考文獻(xiàn):
[1]Ben Forta.正則表達(dá)式必知必會[M].北京:人民郵電出版社,2007.
[2]Matt Butcher. Go語言實(shí)戰(zhàn)[M].北京:機(jī)械工業(yè)出版社,2019.
【通聯(lián)編輯:謝媛媛】
收稿日期:2019-10-19
作者簡介:劉華煜(1976-),男,洛陽師范學(xué)院教師,主要研究方向?yàn)橛?jì)算機(jī)軟件開發(fā)及應(yīng)用;蔣維(1981-),女,洛陽師范學(xué)院教師,千要研究方向?yàn)橛?jì)算機(jī)應(yīng)用與技術(shù)。