Python_实现json数据的jsonPath(精简版)定位及增删改操作
基于python实现json数据的jsonPath(精简版)定位及增删改操作
by:授客 QQ:1033553122
实践环境
win7 64
Python 3.4.0
代码
#-*- encoding:utf-8 -*-
# author:授客
import re
def parse_sub_expr(sub_expr):
'''
解析字表达式-元素路径的组成部分
:param sub_expr:
:return:
'''
RIGHT_INDEX_DEFAULT = '200000000' # 右侧索引的默认值 未指定右侧索引时使用,形如 key[2:]、key[:]
result = re.findall('\[.+\]', sub_expr)
if result: # 如果子表达式为数组,形如 [1]、key[1]、 key[1:2]、 key[2:]、 key[:3]、key[:]
array_part = result[0]
array_part = array_part.lstrip('[').rstrip(']')
key_part = sub_expr[:sub_expr.index('[')]
if key_part == '$': # 如果key为 $ ,为根,替换为数据变量 json_data
key_part = JSON_DATA_VARNAME
elif key_part == '*':
key_part == '\[.+\]' # 如果key为 * ,替换为 \[\.+\] 以便匹配 ["key1"]、["key2"]、……
else:
key_part = '\["%s"\]' % key_part
if array_part == '*': # 如果数组索引为 * ,替换为 \[\d+\] 以便匹配 [0]、[1]、……
array_part = '\[\d+\]'
else:
array_part_list = array_part.replace(' ', '').split(':')
left_index = array_part_list[0:1]
right_index = array_part_list[1:]
if left_index:
left_index = left_index[0]
if not (left_index or left_index.isdigit()): # 为空字符串、非数字
left_index = '0'
else:
left_index = '0'
if right_index:
right_index = right_index[0]
if not (right_index or right_index.isdigit()):
right_index = RIGHT_INDEX_DEFAULT # 一个比较大的值,
array_part = left_index + '-' + right_index
else:
array_part = left_index
array_part = '\[[%s]\]' % array_part # 数组索引设置为 \[[n-m]\],以便匹配[n],[n+1], ……,[m-1]
return key_part + array_part
elif sub_expr == '*':
sub_expr = '\[.+\]'
elif sub_expr == '$':
sub_expr = JSON_DATA_VARNAME
else:
sub_expr = '\["%s"\]' % sub_expr
return sub_expr
def parse_json(json_data, data_struct_link):
'''
递归解析json数据结构,存储元素的路径
:param json_data:
:param data_struct_link:
:return:
'''
if type(json_data) == type({}): # 字典类型
keys_list = json_data.keys()
for key in keys_list:
temp_data_struct_link = data_struct_link + '["%s"]' % key
if type(json_data[key]) not in [type({}), type([])]: # key对应的value值既不是数组,也不是字典
data_struct_list.append(temp_data_struct_link)
else:
parse_json(json_data[key], temp_data_struct_link)
elif type(json_data) == type([]): # 数组类型
array_length = len(json_data)
for index in range(0, array_length):
temp_json_data = json_data[index]
keys_list = temp_json_data.keys()
for key in keys_list:
temp_data_struct_link = data_struct_link + '[%s]["%s"]' % (str(index), key)
if type(temp_json_data[key]) not in [type({}), type([])]: # key对应的value值既不是数组,也不是字典
data_struct_list.append(temp_data_struct_link)
else:
parse_json(temp_json_data[key], temp_data_struct_link)
if __name__ == '__main__':
json_data = [{"data": [{
"admin": "string|集群负责人|||",
"components": [
{
"clusterId": "integer|组件所属的集群 id|||",
"createTime": "string|组件创建时间|||",
"description": "string|组件描述|||",
"enabled": "boolean|组件是否开启||false|",
},
{
"clusterId": "integer|组件所属的集群 id|||",
"createTime": "string|组件创建时间|||",
"description": "string|组件描述|||",
"enabled": "boolean|组件是否开启||false|",
}
],
"createTime": "string|集群创建时间|||",
"description": "string|集群描述|||",
"enabled": "boolean|集群是否开启||false|",
"id": "integer|集群 id|||",
"modifyTime": "string|集群修改时间|||",
"name": "string|集群名|||"
}],
"errMsg": "string||||",
"ok": "boolean||||",
"status": "integer||||"
}]
JSON_DATA_VARNAME = 'json_data' # 存在json数据的变量名称
data_struct_list = [] # 用于存放所有 json 元素路径,形如 json_data[0]["data"][0]["components"][0]["enabled"]
data_struct_link = 'json_data' # 用于临时存放单条json 元素路径(的一部分)
parse_json(json_data, data_struct_link)
print('获取的json元素路径,元素值如下:')
for item in data_struct_list:
print(item, '\t', eval(item))
# 测试用表达式
# expr = '$.data[*].components[0]' # json数据为字典 形如 {……}
# expr = '$[*].data[0:1].components[*]' # json数据为数组 形如 [{……}]
expr = 'data[0:1].components[*]'
# expr = 'data[0:1].components'
# 解析表达式为正则表达式
re_pattern = ''
for sub_expr in expr.split('.'):
re_pattern += parse_sub_expr(sub_expr)
print('\n元素路径jsonpath表达式为:%s' % expr)
print('元素路径正则表达式re pattern为:%s' % re_pattern)
print('\njsonpath 匹配结果如下:')
re_pattern = re.compile(re_pattern)
target_set = set() # 匹配结果会有重复值,所以采用集合
for item in data_struct_list:
results = re.findall(re_pattern, item)
for result in results:
print('匹配的元素路径jsonpath为:%s' % item)
print('正则匹配结果为:%s' % result)
target = item[0:item.index(result) + len(result)]
print('供提取数据使用的jsonpath为:%s' % target)
print('提取的结果值为:%s \n' % eval(target))
target_set.add(target)
# 通过匹配提取的目标结果,操作json串
for item in target_set:
target = eval(item)
if type(target) == type({}): # 如果为字典
# 更改键的值
target['clusterId'] = 10
# 新增键值对
target['new_key'] = 'key_value'
# 更改键的名称,可以考虑先复制旧的键值,赋值给新的键,然后删除旧的键
target['description_new'] = target['description']
# 删除键值对
del target['description']
elif type(target) == type([]):
# 暂不实现
pass
print(json_data)
运行结果截图:
Python_实现json数据的jsonPath(精简版)定位及增删改操作的更多相关文章
- (数据科学学习手札126)Python中JSON结构数据的高效增删改操作
本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 在上一期文章中我们一起学习了在Python ...
- Java读取json文件并对json数据进行读取、添加、删除与修改操作
转载:http://blog.csdn.net/qing_yun/article/details/46865863#t0 1.介绍 开发过程中经常会遇到json数据的处理,而单独对json数据进行 ...
- Django项目的创建与介绍.应用的创建与介绍.启动项目.pycharm创建启动项目.生命周期.三件套.静态文件.请求及数据.配置Mysql完成数据迁移.单表ORM记录的增删改查
一.Django项目的创建与介绍 ''' 安装Django #在cmd中输入pip3 #出现这个错误Fatal error in launcher: Unable to create process ...
- Elasticsearch6.8.6版本 在head插件中 对数据的增删改操作
一.访问ES方法:http://IP:PORT/ 一.创建索引:head插件创建索引的实例:在"索引"-"新建索引"中创建索引名称,默认了分片与副本情况: 直接 ...
- [MongoDB] - 数据的增删改操作
在前一篇中简单的介绍了一些基本操作命令,现在分别针对这些命令进行比较详细的说明: 一.数据插入 插入数据使用命令insert,insert的参数只有一个,就是要插入的文档BSON数据.MongoDB的 ...
- mysql常用基础操作语法(三)~~对数据的增删改操作【命令行模式】
1.插入单条数据:insert into tablename(字段名1,字段名2,...) values(值1,值2,...); 从图中可以看出,插入时不需要每个字段都有值(在没有相关的约束前提下), ...
- C#,记录--一个方法中,完成对数据增删改操作
实际应用中,一般不会使用delete彻底的删除数据,大多都是逻辑删除 为了不把本文写成小作文,举个小栗子吧 表 A,deletestate为置删除字段,int类型,值为0和1 表中五条数据 查询 se ...
- python学习之老男孩python全栈第九期_数据库day001知识点总结 —— MySQL操作数据库以及数据表、基本数据类型、基本增删改查、外键定义以及创建
一. 学习SQL语句规则以及外键 1. 操作文件夹 create database db2; 创建文件夹 create database db2 default charset utf8; 创建文件夹 ...
- sql 触发器 针对一张表数据写入 另一张表 的增删改
ALTER TRIGGER [dbo].[tri_test2] ON [dbo].[student] for INSERT,DELETE,UPDATEAS BEGIN if not exists (s ...
随机推荐
- [Swift]LeetCode461. 汉明距离 | Hamming Distance
The Hamming distance between two integers is the number of positions at which the corresponding bits ...
- [Swift]LeetCode972.相等的有理数 | Equal Rational Numbers
Given two strings S and T, each of which represents a non-negative rational number, return True if a ...
- SQL执行错误#1064---保留字错误
CREATE TABLE IF NOT EXISTS `change` ( `id` INT NOT NULL AUTO_INCREMENT, `creator` VARCHAR(45) NOT NU ...
- 002-J2EE-tomcat的配置
在配置之前我们要先下载一个Tomcat,登入以下网址... 下载解压完了之后可以把里面多余的东西删掉,当然也可以选择不删. 还有这里的也是 如果已经有了 classes 和l ib 目录了, 就不用再 ...
- slf4j 和 log4j的关系及合用Maven配置
最近因为项目实在是太忙,都没有时间学习.有时候会很矛盾,一方面是全心全意的想去快速做完项目,一方面又想学习点新东西.这样导致这两三个月都没有去学习一些新的东西,这周我开始创建自己的maven项目,因为 ...
- 【Spark篇】---Spark调优之代码调优,数据本地化调优,内存调优,SparkShuffle调优,Executor的堆外内存调优
一.前述 Spark中调优大致分为以下几种 ,代码调优,数据本地化,内存调优,SparkShuffle调优,调节Executor的堆外内存. 二.具体 1.代码调优 1.避免创建重复的RDD,尽 ...
- 成熟的 Git 分支模型
个人博客原文: 成熟的 Git 分支模型 今天介绍一下工作中会用到的 Git 分支模型. 先贴上图以表敬意 闲言 在学校不管是自己写课程设计还是给老师做项目,有 2 到 3 个人一起协作开发时就会使用 ...
- 【java提高】---java反射机制
java反射机制 一.概述 1.什么是反射机制 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态 ...
- Nginx+Tomcat搭建集群,Spring Session+Redis实现Session共享
小伙伴们好久不见!最近略忙,博客写的有点少,嗯,要加把劲.OK,今天给大家带来一个JavaWeb中常用的架构搭建,即Nginx+Tomcat搭建服务集群,然后通过Spring Session+Redi ...
- 预测python数据分析师的工资
前两篇博客分别对拉勾中关于 python 数据分析有关的信息进行获取(https://www.cnblogs.com/lyuzt/p/10636501.html)和对获取的数据进行可视化分析(http ...