基于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(精简版)定位及增删改操作的更多相关文章

  1. (数据科学学习手札126)Python中JSON结构数据的高效增删改操作

    本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 在上一期文章中我们一起学习了在Python ...

  2. Java读取json文件并对json数据进行读取、添加、删除与修改操作

    转载:http://blog.csdn.net/qing_yun/article/details/46865863#t0   1.介绍 开发过程中经常会遇到json数据的处理,而单独对json数据进行 ...

  3. Django项目的创建与介绍.应用的创建与介绍.启动项目.pycharm创建启动项目.生命周期.三件套.静态文件.请求及数据.配置Mysql完成数据迁移.单表ORM记录的增删改查

    一.Django项目的创建与介绍 ''' 安装Django #在cmd中输入pip3 #出现这个错误Fatal error in launcher: Unable to create process ...

  4. Elasticsearch6.8.6版本 在head插件中 对数据的增删改操作

    一.访问ES方法:http://IP:PORT/ 一.创建索引:head插件创建索引的实例:在"索引"-"新建索引"中创建索引名称,默认了分片与副本情况: 直接 ...

  5. [MongoDB] - 数据的增删改操作

    在前一篇中简单的介绍了一些基本操作命令,现在分别针对这些命令进行比较详细的说明: 一.数据插入 插入数据使用命令insert,insert的参数只有一个,就是要插入的文档BSON数据.MongoDB的 ...

  6. mysql常用基础操作语法(三)~~对数据的增删改操作【命令行模式】

    1.插入单条数据:insert into tablename(字段名1,字段名2,...) values(值1,值2,...); 从图中可以看出,插入时不需要每个字段都有值(在没有相关的约束前提下), ...

  7. C#,记录--一个方法中,完成对数据增删改操作

    实际应用中,一般不会使用delete彻底的删除数据,大多都是逻辑删除 为了不把本文写成小作文,举个小栗子吧 表 A,deletestate为置删除字段,int类型,值为0和1 表中五条数据 查询 se ...

  8. python学习之老男孩python全栈第九期_数据库day001知识点总结 —— MySQL操作数据库以及数据表、基本数据类型、基本增删改查、外键定义以及创建

    一. 学习SQL语句规则以及外键 1. 操作文件夹 create database db2; 创建文件夹 create database db2 default charset utf8; 创建文件夹 ...

  9. sql 触发器 针对一张表数据写入 另一张表 的增删改

    ALTER TRIGGER [dbo].[tri_test2] ON [dbo].[student] for INSERT,DELETE,UPDATEAS BEGIN if not exists (s ...

随机推荐

  1. 吴恩达机器学习笔记52-异常检测的问题动机与高斯分布(Problem Motivation of Anomaly Detection& Gaussian Distribution)

    一.问题动机 异常检测(Anomaly detection)问题是机器学习算法的一个常见应用.这种算法的一个有趣之处在于:它虽然主要用于非监督学习问题,但从某些角度看,它又类似于一些监督学习问题. 给 ...

  2. [SQL]LeetCode185. 部门工资前三高的员工 | Department Top Three Salaries

    SQL 架构 Create table If Not Exists Employee (Id ), Salary int, DepartmentId int) Create table If Not ...

  3. [Swift]LeetCode967. 连续差相同的数字 | Numbers With Same Consecutive Differences

    Return all non-negative integers of length N such that the absolute difference between every two con ...

  4. 一张图看懂STM32芯片型号的命名规则

    意法半导体已经推出STM32基本型系列.增强型系列.USB基本型系列.增强型系列:新系列产品沿用增强型系列的72MHz处理频率.内存包括64KB到256KB闪存和 20KB到64KB嵌入式SRAM.新 ...

  5. ASP.NET Core 2.0 MVC - 获取当前登录用户信息

    一.前言 上篇实战完成后,没想到会有那么多的圈友给了那么多的支持,甚至连只是作为代码仓储的git上也给了一些小星星,真的感觉很惶恐啊,哈哈哈,毕竟代码写的很烂啊.由于上一篇只是大概说了下项目,所以准备 ...

  6. redis 系列13 集合对象

    一. 集合对象概述 这里的集合是string类型的无序集合,在集合对象中集合成员是唯一的,这就意味着集合中不能出现重复的数据.集合是通过哈希表实现的,集合中最大的成员数为 232-1 (4294967 ...

  7. 前端笔记之JavaScript(十一)event&BOM&鼠标/盒子位置&拖拽/滚轮

    一.事件对象event 1.1 preventdefault()和returnValue阻止默认事件 通知浏览器不要执行与事件关联的默认动作. preventdefault()  支持Chrome等高 ...

  8. 基于spark实现并行化Apriori算法

    详细代码我已上传到github:click me 一. 实验要求         在 Spark2.3 平台上实现 Apriori 频繁项集挖掘的并行化算法.要求程序利用 Spark 进行并行计算. ...

  9. Python爬虫实例:爬取豆瓣Top250

    入门第一个爬虫一般都是爬这个,实在是太简单.用了 requests 和 bs4 库. 1.检查网页元素,提取所需要的信息并保存.这个用 bs4 就可以,前面的文章中已经有详细的用法阐述. 2.找到下一 ...

  10. java nginx等代理或网关转发请求后获取客户端的ip地址,原理

    在没有网关或者反向代理软件情况下,java里获取客户端ip地址的方法是request.getRemoteAddr() 先解释下http协议和TCP协议: 网页默认是进行http连接了,http协议即超 ...