当前位置: 首页 > article >正文

从复合字符串中分割并解析多个JSON字符串

起因

遇到一个情况,在一个字符串中包含了多个json字符串,在后续的处理中需要将其分解开,分成多个独立的json字符串。
在网上找了一下没有找到比较好的处理方法,那么决定自己写一个。

分析

首先,json是通过 {} 包裹的,并且是可以嵌套的。因此,从第一个 { 开始,遇到与左右大括号相等的数量时候,认为是截取出来一个json字符串。
其次,上面的情况是一种理想状态,因为json字符串中的key或者value中是可能也存在"{“和”}"的,需要排除这种状况,也就是遇到在key或者value中的情况是不能将其当做分隔符号的。那么需要通过分析,将key或者value本身是字符串,且忽略内部的大括号。
再次,分割key和value的字符串的时候,其使用单双引号包围,需要排除是单双引号转义的情况。
最后,收集每个json字符串中间的内容,则能够将其分解开。

代码实现

解析字符串时候,分为三种状态,使用枚举值,如下所示:

    enum class ParseStage
    {
        FIND_START_TAG,
        PARSING_JSON,
        PARSING_STRING
    };

分割的代码如下:

		// jsons -- 分割后的结果
		// jsonStr -- 输入的原始字符串
    std::vector<std::string> jsons;
    std::string tmpJson;
    ParseStage parseStage = ParseStage::FIND_START_TAG;
    int tagNextIndex = 0;
    char lastChar = '\0';
    char stringSpliter = '\0';
    bool resetLastCheckChar = false;
    for (const char& tmpChar : jsonStr) {
        if(parseStage == ParseStage::FIND_START_TAG)
        {
            if(tmpChar == '{')
            {
                parseStage = ParseStage::PARSING_JSON;
                tmpJson += tmpChar;
                tagNextIndex = 1;
            }
        }
        else if(parseStage == ParseStage::PARSING_JSON)
        {
            tmpJson += tmpChar;
            if(tmpChar == '{')
            {
                tagNextIndex ++;
            }

            if(tmpChar == '}')
            {
                tagNextIndex --;
            }

            if(tagNextIndex == 0)
            {
                jsons.emplace_back(tmpJson);
                parseStage = ParseStage::FIND_START_TAG;
                tmpJson.clear();
            }

            if(tmpChar == '\'' || tmpChar == '"')
            {
                stringSpliter = tmpChar;
                parseStage = ParseStage::PARSING_STRING;
            }
        }
        else if(parseStage == ParseStage::PARSING_STRING)
        {
            tmpJson += tmpChar;
            if(tmpChar == '\\' && lastChar == '\\')
            {
                resetLastCheckChar = true;
            }

            if(tmpChar == stringSpliter && lastChar != '\\')
            {
                parseStage = ParseStage::PARSING_JSON;
            }
        }
        else
        {
            ; // do nothing
        }


        if(!resetLastCheckChar)
        {
            lastChar = tmpChar;
        }
        else
        {
            lastChar = '\0';
        }
    }

代码受控地址与版权

以上代码是MIT协议,代码受控在Github https://github.com/chinanewer/SimpleJsonSplitter.git, 如果要使用请注意版权声明。
在代码受控的仓库中有使用示例。


http://www.kler.cn/a/406424.html

相关文章:

  • C#桌面应用制作计算器进阶版01
  • IDEA2023 SpringBoot整合MyBatis(三)
  • 高阶C语言补充:柔性数组
  • 自由学习记录(23)
  • 在 Ubuntu 系统上安装 npm 环境以及 nvm(Node Version Manager)
  • MybatisPlus之1:快速入门
  • VR虚拟现实技术的应用领域有哪些?
  • 长文解读:OSAID 1.0,全球首个开源AI标准,审视探讨其对AI行业实践开源的影响
  • React 表单Form 中的 useWatch
  • 《Vue零基础教程》(3)创建第一个应用案例
  • java使用itext生成pdf
  • shell--第一次作业
  • 微信小程序组件详解:text 和 rich-text 组件的基本用法
  • 定长滑动窗口基础模板题:LeetCode——2379.得到K个黑块的最少涂色次数和643.子数组最大平均数 1
  • 数据结构-树状数组专题(2)
  • 商业物联网:拥抱生产力的未来
  • 2024年9月中国电子学会青少年软件编程(Python)等级考试试卷(六级)答案 + 解析
  • 基于Java Springboot旅游民宿信息管理系统
  • Linux 进程概念与进程状态
  • Elasticsearch实战应用:构建高效搜索与分析平台
  • nodejs基于微信小程序的云校园的设计与实现
  • AFSim脚本学习
  • 未来已来:少儿编程竞赛聚焦物联网,激发创新潜力
  • vue3-基于element-plus实现定制化动态表单及校验
  • CentOS使用中遇到的问题及解决方法
  • java的强,软,弱,虚引用介绍以及应用