标题 | 用正则表达式处理缩写班级字符串 |
范文 | 刘华煜 蒋维 摘要:如何把缩写的班级字符串分拆成单独的班级是一件麻烦事。用正则表达式能很好地解决这个问题。 关键词:正则表达式;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-),女,洛阳师范学院教师,千要研究方向为计算机应用与技术。 |
随便看 |
|
科学优质学术资源、百科知识分享平台,免费提供知识科普、生活经验分享、中外学术论文、各类范文、学术文献、教学资料、学术期刊、会议、报纸、杂志、工具书等各类资源检索、在线阅读和软件app下载服务。