python實現命令行工具jq的json路徑過濾

 2023-12-25 阅读 28 评论 0

摘要:開發過程中訪問接口時經常用到jq來過濾json,用著覺得不是很爽,于是自己搞一個舒服的 ^_^ 先說需求: 輸入:參數1:被過濾對象(json、dict、list), 參數2:過濾路徑 輸出:過濾結果(python對象),默認格式化輸出結果,key按字母順序

開發過程中訪問接口時經常用到jq來過濾json,用著覺得不是很爽,于是自己搞一個舒服的 ^_^

先說需求:

輸入:參數1:被過濾對象(json、dict、list), 參數2:過濾路徑

輸出:過濾結果(python對象),默認格式化輸出結果,key按字母順序排列

支持過濾方式:

  • dict key過濾 .key

  • dict key列表 .keys()

  • dict value列表 .values()

  • dict key,value對 .iterms()

  • list過濾 .3 或 .[3]

  • list負索引 .-2 或 .[-2]

  • list切片1 .2:6 或 .[2:6]

  • list切片2 .2: 或 .[2:]

  • list切片3 .:6 或 .[:6]

  • list step1 .1:6:2 或 .[1:6:2]

  • list step2 .1::2 或 .[1::2]

  • list step3 .::2 或 .[::2]

  • string過濾..與list相同

  • string切片..與list相同

  • string 切片 step..與list相同

廢話不多說,直接上核心代碼,兼容Py2和Py3

from __future__ import unicode_literalsimport json
import sixdef ppt(obj, path='.', with_print=True, normal_path_print=False):base_string = str if six.PY3 else basestringobj = json.loads(obj) if isinstance(obj, base_string) else objfind_str, find_map = '', ['["%s"]', '[%s]', '%s', '.%s']for im in path.split('.'):if not im:continueif isinstance(obj, (list, tuple, base_string)):if im.startswith('[') and im.endswith(']'):im = im[1:-1]if ':' in im:slice_default = [0, len(obj), 1]obj, quota = obj[slice(*[int(sli) if sli else slice_default[i] for i, sli inenumerate(im.split(':'))])], 1else:obj, quota = obj[int(im)], 1else:if im in obj:obj, quota = obj[im], 0elif im.endswith('()'):obj, quota = list(getattr(obj, im[:-2])()), 3else:if im.isdigit():obj, quota = obj[int(im)], 1else:raise KeyError(im)find_str += find_map[quota] % imif with_print:print(obj if isinstance(obj, base_string) elsejson.dumps(obj,indent=4,sort_keys=True,ensure_ascii=False))if normal_path_print:print('get it normally with: <obj>%s' % find_str)return obj

函數名:ppt,pretty print, 想不起更好的簡短的命名了 ?_?

參數說明:

  • obj 輸入的對象
  • path='.' 過濾字符串
  • with_print=True 是否格式化打印輸出過濾結果
  • normal_path_print=False 是否輸出過濾器反解后的正常查找方式

舉例:

> test = '{"a": [1, 3, 4, 9, 10, 0, 5, 3, 7], "c": [{"h": 1, "d": [{"e": ["f", "g"]}]}], "b": "1234567890", "d": null}'
> ppt(test)
{"a": [1, 3, 4, 9, 10, 0, 5, 3, 7], "b": "1234567890", "c": [{"d": [{"e": ["f", "g"]}], "h": 1}], "d": null
}

上述輸出key按字母順序排序

> ppt(test, '.a.::2', normal_path_print=True)
[1, 4, 10, 5, 7
]
get it normally with: <obj>["a"][::2]
> ppt(test, '.c.0.keys()', normal_path_print=True)
["h", "d"
]
get it normally with: <obj>["c"][0].keys()

方便的地方:

如 一個復雜的引用數據的方式
['all_angles'][0]['nodes'][-1]['children'][1]['children'][3]['id']
換用更簡單的方式,可以更簡單快速的定位數據:
'all_angles.0.nodes.-1.children.1.children.3.id'

轉載于:https://www.cnblogs.com/yun-code/p/8287553.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/194981.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息