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

server/2024/11/24 10:59:07/

起因

遇到一个情况,在一个字符串中包含了多个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.ppmy.cn/server/144521.html

相关文章

信号signal

信号&#xff0c;signal 信号是一种软件中断机制&#xff0c;基于该机制能实现进程间通信&#xff0c;故信号是实现进程通信的一种方式。 信号由内核线程或者用户线程发起生成&#xff0c;例如&#xff0c;SIGINT 信号通常由用户通过按下 CtrlC 产生。 内核中会保存每个进程的…

http/https

1、http与https HTTPHTTPS信息明文传输加入ssl加密传输协议&#xff0c;可以使得报文加密传输默认端口80默认端口443连接简单TCP三次握手通信TCP三次握手后还要SSL/TLS握手过程&#xff0c;才可以加密报文传输无状态不安全需要到CA申请证书&#xff0c;身份认证&#xff0c;自…

reactflow 中 useReactFlow 模块作用

1. 访问 ReactFlow 核心实例和状态 它允许组件访问 ReactFlow 的核心实例及其相关状态。这意味着组件可以获取到有关整个流程图的关键信息&#xff0c;例如当前的缩放级别、视口的位置和大小等。 2. 操作 ReactFlow 实例方法 除了获取状态&#xff0c;useReactFlow还提供了操…

shell与QQ邮箱的连接

1.下载软件&#xff1a;yum install s-nail 2.配置文件&#xff1a;vim /etc/s-nail.rc 末尾添加此三行&#xff0c;加入QQ邮箱和验证码 3.验证码位于QQ邮箱安全管理内&#xff0c;进行复制粘贴 4.测试发消息给本地邮箱&#xff1a;echo "要发送的内容" | mail …

关于安卓模拟器或手机设置了BurpSuite代理和安装证书后仍然抓取不到APP数据包的解决办法

免责申明 本文仅是用于学习研究安卓系统设置代理后抓取不到App数据包实验,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》【学法时习之丨网络安全在身边一…

[ruby on rails] 安装docker

1. docker安装 ubuntu14.04后自带docker安装包&#xff0c;可以直接安装docker.io sudo apt-get updatesudo apt-get install -y docker.io # 安装后启动sudo service docker start最新版本docker 安装docker-ce # 官方源 curl -fsSL https://download.docker.com/linux/ubun…

CentOS:A服务器主动给B服务器推送(上传),B服务器下载A服务器文件(下载)

Linux:常识(bash: ip command not found )_bash: ip: command not found-CSDN博客 rsync 中断后先判断程序是否自动重连:ps aux | grep rsync 查看目录/文件是否被使用(查询线程占用):lsof /usr/local/bin/mongodump/.B_database1.6uRCTp 场景:MongoDB中集合非常大需要…

Mistral推出“Le Chat”,对标ChatGPT

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…