@@ -53,7 +53,7 @@ class JSONPath:
5353 # operators
5454 REP_SLICE_CONTENT = re .compile (r"^(-?\d*)?:(-?\d*)?(:-?\d*)?$" )
5555 REP_SELECT_CONTENT = re .compile (r"^([\w.']+)(, ?[\w.']+)+$" )
56- REP_FILTER_CONTENT = re .compile (r"@\.(. *?)(?=<=|>=|==|!=|>|<| in| not| is)|len\(@\.( .*?)\)" )
56+ REP_FILTER_CONTENT = re .compile (r"@([.\[]. *?)(?=<=|>=|==|!=|>|<| in| not| is)|len\(@([.\[] .*?)\)" )
5757
5858 # annotations
5959 f : list
@@ -94,15 +94,15 @@ def _parse_expr(self, expr):
9494 # pick up special patterns
9595 expr = JSONPath .REP_GET_QUOTE .sub (self ._get_quote , expr )
9696 expr = JSONPath .REP_GET_BACKQUOTE .sub (self ._get_backquote , expr )
97+ expr = JSONPath .REP_GET_PAREN .sub (self ._get_paren , expr )
9798 expr = JSONPath .REP_GET_BRACKET .sub (self ._get_bracket , expr )
9899 expr = re .sub (r"\.(\.#B)" , r"\1" , expr )
99- expr = JSONPath .REP_GET_PAREN .sub (self ._get_paren , expr )
100100 # split
101101 expr = JSONPath .REP_DOUBLEDOT .sub (f"{ JSONPath .SEP } ..{ JSONPath .SEP } " , expr )
102102 expr = JSONPath .REP_DOT .sub (JSONPath .SEP , expr )
103103 # put back
104- expr = JSONPath .REP_PUT_PAREN .sub (self ._put_paren , expr )
105104 expr = JSONPath .REP_PUT_BRACKET .sub (self ._put_bracket , expr )
105+ expr = JSONPath .REP_PUT_PAREN .sub (self ._put_paren , expr )
106106 expr = JSONPath .REP_PUT_BACKQUOTE .sub (self ._put_backquote , expr )
107107 expr = JSONPath .REP_PUT_QUOTE .sub (self ._put_quote , expr )
108108 if expr .startswith ("$;" ):
@@ -147,12 +147,15 @@ def _put_paren(self, m):
147147 @staticmethod
148148 def _gen_obj (m ):
149149 content = m .group (1 ) or m .group (2 ) # group 2 is for len()
150- ret = "__obj"
151- for e in content .split ("." ):
152- if len (e ) >= 2 and ((e [0 ] == "'" and e [- 1 ] == "'" ) or (e [0 ] == '"' and e [- 1 ] == '"' )):
153- e = e [1 :- 1 ]
154- ret += f'["{ e } "]'
155- return ret
150+
151+ def repl (m ):
152+ g = m .group (1 )
153+ if g [0 ] in ("'" , '"' ):
154+ return f"[{ g } ]"
155+ return f"['{ g } ']"
156+
157+ content = re .sub (r"\.(\w+|'[^']*'|\"[^\"]*\")" , repl , content )
158+ return "__obj" + content
156159
157160 @staticmethod
158161 def _traverse (f , obj , i : int , path : str , * args ):
@@ -275,6 +278,8 @@ def _trace(self, obj, i: int, path):
275278 if step .startswith ("?(" ) and step .endswith (")" ):
276279 step = step [2 :- 1 ]
277280 step = JSONPath .REP_FILTER_CONTENT .sub (self ._gen_obj , step )
281+ if isinstance (obj , dict ):
282+ self ._filter (obj , i + 1 , path , step )
278283 self ._traverse (self ._filter , obj , i + 1 , path , step )
279284 return
280285
0 commit comments