万军之中取上将首级 武器-正则

128 阅读2分钟

身为一名合格的 coder,若真需求来犯,闲某唯有一剑破之,剑名 - 正则。

需求:给出任意结构的 json,取出想要的字段集合。

肉眼识别着实不太符合一名 coder 的身份,因为不知其 json 结构所以首先想到的肯定便是正则表达式。

随便来个 json,作为我们的实例

{
  "code": null,
  "msg": null,
  "success": true,
  "data": [
    {
      "id": 2206,
      "shopId": 344947,
      "tid": "211221170152100051",
      "sendNick": null,
      "sendName": "测试数据",
      "sendMobile": "17666666666",
      "sendPhone": "",
      "sendProvince": "山东省",
      "sendCity": "临沂市",
      "sendDistrict": "兰山区",
      "sendAddr": "测试地址",
      "recNick": null,
      "recName": "小考拉",
      "recMobile": "1366666666",
      "recPhone": "",
      "recProvince": "浙江省",
      "recCity": "杭州市",
      "recDistrict": "余杭区",
      "recAddr": "测试地区",
      "inputType": 99,
      "created": "2021-12-21 17:01:52",
      "remark": ""
    },
    {
      "id": 2207,
      "shopId": 344947,
      "tid": "211221170152100052",
      "sendNick": null,
      "sendName": "测试数据",
      "sendMobile": "17666666666",
      "sendPhone": "",
      "sendProvince": "山东省",
      "sendCity": "临沂市",
      "sendDistrict": "兰山区",
      "sendAddr": "测试地址",
      "recNick": null,
      "recName": "小考拉",
      "recMobile": "1366666666",
      "recPhone": "",
      "recProvince": "浙江省",
      "recCity": "杭州市",
      "recDistrict": "余杭区",
      "recAddr": "测试地区",
      "inputType": 99,
      "created": "2021-12-21 17:01:52",
      "remark": ""
    },
    {
      "id": 2208,
      "shopId": 344947,
      "tid": "211221170152100053",
      "sendNick": null,
      "sendName": "测试数据",
      "sendMobile": "17666666666",
      "sendPhone": "",
      "sendProvince": "山东省",
      "sendCity": "临沂市",
      "sendDistrict": "兰山区",
      "sendAddr": "测试地址",
      "recNick": null,
      "recName": "小考拉",
      "recMobile": "1366666666",
      "recPhone": "",
      "recProvince": "浙江省",
      "recCity": "杭州市",
      "recDistrict": "余杭区",
      "recAddr": "测试地区",
      "inputType": 99,
      "created": "2021-12-21 17:01:52",
      "remark": ""
    }
  ],
  "total": 3,
  "ext": null
}

首先因为不知道提供的 json 是否是格式化后的还是没有格式化的,我们需要先去除一些多余字符

let str = JSON.stringify(json).replace(new RegExp('\\\\"', "gm"), '"');
str = str.replace(/[\r\n\s+]/g, "");

然后我们通过正则定位到我们需要的字段

const fieldsReg = /(?<=(\"tid\":\")).*?(?=(\"))/g;
let fields = str.match(fieldsReg);

最后我们的方法就得到了

const getFields = (json) => {
  // 首先去除一些多余字符
  let str = JSON.stringify(json).replace(new RegExp('\\\\"', "gm"), '"');
  str = str.replace(/[\r\n\s+]/g, "");
  // 利用正则精准定位字段
  const fieldsReg = /(?<=(\"tid\":\")).*?(?=(\"))/g;
  let fields = str.match(fieldsReg);
  // 最后将获取到的 tids 去除重复的
  return Array.from(new Set(fields));
};

到这里基本上就完成了,有时候我们认为很复杂的东西,实际上很简单只是我们想复杂了。

目前还有个问题是如果字段是 number 类型,我们应该如何取值呢?欢迎大家指出不足,让我们一起不断进步