: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
(
'
\n
jsonpath
匹配结果如下:
'
)
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
([]):
#
暂不实现
print
(json_data)
运行结果截图:
友情提示:
限于时间仓促,文中可能存在错误,欢迎指正、评论!
作者五行缺钱,如果觉得文章对您有帮助,请扫描下边的二维码打赏作者,金额随意
,您的支持将是我继续创作的源动力,
打赏后如有任何疑问,请联系我!!!
支付宝打赏 全国软件测试交流QQ群