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