程序员不加班的妙招(四)—— 正则表达式批量读写同类型配置项
目录
一、引言
二、正文
1.生成配置结构体
2.生成read函数
3.生成write函数
三、结语
一、引言
软件开发过程中,经常会遇到读写配置文件的情况,随着业务复杂度的提升,配置文件中配置项的数量会剧增,通过硬编码的方式实现配置读写,既低效又易错。
今天我们带来一种通过正则表达式,快速生成配置文件读写代码的方法。
达成的效果如下图1和图2所示(以使用Qt读写json为例):

图 1一键生成配置结构体

图 2一键生成read函数
tip:本文档中使用的编辑工具为 Visual Studio Code v1.103.2
二、正文
本文中介绍的使用正则表达式快速生成配置读写代码的方式。此方法适用于读写同类型配置项的情况,后续文章中将介绍混合类型配置项读写的方法。
拿到编写好的配置文件后,需要编写3组正则表达式,分别用于生成配置结构体、生成read函数,生成write函数。
配置文件全文如下:
{
"userName":"ZhangSan",
"userAge":"28",
"userEmail":"zhangsan@example.com",
"userPhone":"13812345678",
"userAddress":"Beijing Chaoyang District",
"userGender":"Male",
"userOccupation":"Software Engineer",
"userCompany":"Tech Innovation Co., Ltd.",
"userEducation":"Bachelor",
"userHobby":"Reading",
"userBirthday":"1996-05-12",
"userCity":"Beijing",
"userProvince":"Beijing",
"userCountry":"China",
"userIDCard":"11010519960512XXXX",
"userSalary":"25000",
"userExperience":"5 years",
"userSkill":"Java,Python,MySQL",
"userStatus":"Active",
"userRemark":"Excellent employee"
}
1.生成配置结构体
通过分析 已有和目标字符串的特点,获取各自匹配的正则表达式,如下表所示
| 项目 | 字符串 | 解释 |
| 已有字符串 | "userName": "ZhangSan", |
|
| 目标字符串 | QString userName; // "ZhangSan", |
|
| 匹配已有字符串的正则 | "(w+)"s*:s*(.*),*$ | “(w+)”:用于匹配json字段中的key,并捕获分组 (.*): 用于匹配json字段中的value,并捕获分组 ,*:用于匹配行尾的“,”在最后一个json字段中不存在所以用量词 *(0个或多个),也可以用 ?(0个或1个) |
| 匹配目标字符串的正则 | QString $1; // $2 | $1: 引用 key,也就是userName $2:应用value,也就是"ZhangSan" : 制表符,用于调整输出字符串的格式 |
接下来,将json中的键值对复制到 struct UserProfile {}中, 执行“全部替换”,得到UserProfile 结构体,如图3所示

图 3一键生成配置结构体
2.生成read函数
通过分析 已有和目标字符串的特点,获取各自匹配的正则表达式,如下表所示
| 项目 | 字符串 | 解释 |
| 已有字符串 | "userName": "ZhangSan", |
|
| 目标字符串 | userName = aJsonObj["userName"].toString(); // "ZhangSan", |
|
| 匹配已有字符串的正则 | "(w+)"s*:s*(.*),*$ | “(w+)”:用于匹配json字段中的key,并捕获分组 (.*): 用于匹配json字段中的value,并捕获分组 ,*:用于匹配行尾的“,”在最后一个json字段中不存在所以用量词 *(0个或多个),也可以用 ?(0个或1个) |
| 匹配目标字符串的正则 | $1 = aJsonObj["$1"].toString(); // $2 | $1: 引用 key,也就是userName $2:应用value,也就是"ZhangSan" : 制表符,用于调整输出字符串的格式 |
接下来,编写函数首部 “void UserProfile::read(const QJsonObject& aJsonObj) ”,将json中的键值对复制到函数体中,执行“全部替换”,得到图4所示read 函数体

图 4一键生成read
说明:此处演示的是如何批量处理文本的功能,并没有进行数据校验,实际工作过程中,可以将读取配置项的代码封装成函数如下所示:
QString GetItemString(const QJsonObject& aJsonObj, QString aKey, QString aDefault)
{
if(aJsonObj.contains(aKey) && aJsonObj[aKey].isString())
{
return aJsonObj[aKey].toString();
}
else{
return aDefault;
}
}
这时只需要将目标正则表达式修改为$1 = GetItemString(aJsonObje,“$1”, “”); // $2 即可.
3.生成write函数
通过分析 已有和目标字符串的特点,获取各自匹配的正则表达式,如下表所示
| 项目 | 字符串 | 解析 |
| 已有字符串 | "userName": "ZhangSan", |
|
| 目标字符串 | aJsonObj["userName"] = userName; // "ZhangSan", |
|
| 匹配已有字符串的正则 | "(w+)"s*:s*(.*),*$ | “(w+)”:用于匹配json字段中的key,并捕获分组 (.*): 用于匹配json字段中的value,并捕获分组 ,*:用于匹配行尾的“,”在最后一个json字段中不存在所以用量词 *(0个或多个),也可以用 ?(0个或1个) |
| 匹配目标字符串的正则 | aJsonObj["$1"] = $1; // $2 | $1: 引用 key,也就是userName $2:应用value,也就是"ZhangSan" : 制表符,用于调整输出字符串的格式 |
接下来,编写函数首部 “ void UserProfile::write(QJsonObject& aJsonObj) ”,将json中的键值对复制到函数体中,执行“全部替换”,得到图5所示write函数体

图 5一键生成write
至此,我们就完成了读写大量同类型配型项的代码,当然,完整功能还需要补充一些加载文件和保存文件的函数代码。
三、结语
通过本章学习,我们掌握了使用正则表达式批量处理海量同类型配置项的方法,避免了硬编码造成的时间浪费,提高了代码的正确性。今天就到这里了,程序员们下班!
更多精彩内容,请关注公众号:飞翔的SA
题外话:如果对正则表达式理解比较吃力请参考以下文档
参考文档:
正则表达式的妙用(一) 初识正则——基础用法
正则表达式的妙用(二) 初识正则——高级用法
正则表达式的妙用(三) 初识正则——补充知识
正则表达式的妙用(四) 初识正则——专业英语







