论文部分内容阅读
摘要:如何把缩写的班级字符串分拆成单独的班级是一件麻烦事。用正则表达式能很好地解决这个问题。
关键词:正则表达式;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-),女,洛阳师范学院教师,千要研究方向为计算机应用与技术。
关键词:正则表达式;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-),女,洛阳师范学院教师,千要研究方向为计算机应用与技术。