前言
前面學了 jsonpath 可以很好的解析 json 數據,提取出我們想要的內容,對於平常的基本工作沒太大的問題,但有一點點小遺憾。
jsonpath 的 python 庫功能並不是很強大,不支持過濾器使用正則表達式,一些常用的函數也不支持,對於一些高級語法並不支持。
看到有小伙伴提到 JMESPath 庫也可以解析json,於是翻閱了下官方文檔,資料很全,功能也很強大
JMESPath 簡介
JMESPath 是 JSON的查詢語言,您可以從JSON文檔中提取和轉換元素,類似於 jsonpath 的另外一個庫。
關於 JMESPath 官方文檔介紹https://jmespath.org/tutorial.html#basic-expressions
使用pip安裝jmespath,github地址https://github.com/jmespath/jmespath.py
pip install jmespath
使用示例1,可以使用search
jmespat h表達式並為其提供數據
import jmespath
path = jmespath.search('foo.bar', {'foo': {'bar': 'baz'}})
print(path) # baz
使用示例2, 與re模塊類似,您可以使用該 compile
函數來編譯 jmespath 表達式,並使用此解析的表達式來執行重復搜索
import jmespath
expression = jmespath.compile('foo.bar')
a = expression.search({'foo': {'bar': 'baz'}})
b = expression.search({'foo': {'bar': 'other'}})
print(a) # baz
print(b) # other
基本表達式
字典取值,根據key名稱取到對應的值
嵌套的字典,可以一層一層取值
list可以根據下標取值
dict嵌套list可以一層一層的取值
切片
如果您曾經在python中使用過切片,那么您已經知道如何使用JMESPath slice。
您可以以最簡單的形式指定開始索引和結束索引。結束索引是您不希望包含在切片中的第一個索引。
讓我們看一些例子。首先,給定一個從0到9的整數數組,讓我們選擇該數組的前半部分:
該切片結果包含元素0、1、2、3和4。不包括索引5的元素。如果要選擇數組的后半部分,可以使用以下表達式:
上面的兩個示例可以簡化。如果開始或步驟被省略值它被假定為開始或數組的末尾。例如:
切片的一般形式是[start:stop:step]。到目前為止,我們已經研究了[start:stop]表單。缺省情況下,步驟值是1,這是指包括在由所指定的范圍中的每個元素開始和 停止值。但是,我們可以使用step值跳過元素。例如,僅從數組中選擇偶數元素。
還要注意在這個例子中,我們省略開始還有停止 值,使用該裝置0的啟動值,10為 停止值。在此示例中,表達式[:: 2]等效於 [0:10:2]。
關於切片的最后一件事是,就像索引單個值一樣,所有值都可以是負數。如果步長值為負,則以相反順序創建切片。例如:
上面的表達式創建一個切片,但順序相反。
列表取值使用 * 通配符
1.取出列表中所有的 first 對應的名稱 people[*].first
2.取出列表中前 2 個 first 對應的名稱 people[:2].first
對象取值使用 * 通配符
1.取出 ops 對象的任意屬性對應的numArgs ops.*.numArgs
子查詢使用 * 通配符
在查詢的結果中繼續使用 * 通配符,查詢的結果是列表的列表
如果我們只想要一個實例所有狀態的列表怎么辦?理想情況下,我們希望結果為[“ running”, “ stopped”, “ terminated”, “ running”]
在這種情況下,我們不在乎實例屬於哪個保留,我們只需要一個狀態列表。可以使用 [] 而不是 [*]
過濾器使用
過濾器表達式是為數組定義的,其一般形式為 [? <表達式> <比較器> <表達式>]
。
常用的比較表達式可以使用 ==
, !=
, <
, <=
, >
, > =
假設我們有一個機器列表,每個機器都有一個名稱和一個 state。我們想要所有正在運行的計算機的名稱
管道表達式
前面在匹配list里面的多個值時候,查詢的結果是一個list,如果我想取出結果里面的第一個可以使用管道符 |
取出people下所有對象的 first 屬性,從結果里面取第一個值: people[*].first | [0]
多選
到目前為止,我們已經研究了JMESPath表達式,這些表達式有助於將JSON文檔縮減為您感興趣的元素。下一個概念, 多選列表和 多選哈希允許您創建JSON元素。這使您可以創建JSON文檔中不存在的元素。多選列表創建一個列表,多選哈希創建一個JSON對象。
這是一個多選列表的示例:people[].[name, state.name]
在上面的表達式中,[name, state.name]部分是一個多選列表。它說要創建一個由兩個元素組成的列表,第一個元素是針對list元素評估名稱表達式的結果,第二個元素是對state.name評估的結果。因此,每個列表元素將創建一個兩個元素列表,並且整個表達式的最終結果是兩個元素列表的列表。
與投影不同,即使結果為null,也始終包含表達式的結果。如果將以上表達式更改為people []。[foo, bar],則每個兩個元素列表將為[null, null]。
多重選擇具有與多重選擇列表相同的基本概念,不同之處在於它會創建哈希而不是數組。使用上面的相同示例,如果我們想創建一個具有兩個鍵Name和 State的兩個元素哈希,則可以使用以下代碼:
函數的使用
JMESPath支持函數表達式,例如:length(people)
函數可用於以強大的方式轉換和過濾數據。可以在此處找到函數的完整列表,並且 函數表達式規范具有完整的詳細信息。
以下是一些功能示例。
本示例在people數組中打印最老的人的名字:
函數也可以與過濾器表達式組合。在下面的示例中,JMESPath表達式在myarray中查找包含字符串foo的所有元素。
上面示例中的@字符表示在myarray中正在評估的當前元素。如果myarray數組中的當前元素包含字符串 foo , 則包含(@,'foo')的表達式將返回 true。
盡管函數表達式規范包含所有詳細信息,但在使用函數時,需要牢記以下幾點:
函數參數具有類型。如果函數的參數類型錯誤,則會發生無效類型錯誤。有一些函數可以進行類型轉換(to_string,to_number),以幫助將參數轉換為正確的類型。
如果以錯誤的參數數量調用函數, 則將發生無效arity。