Skip to content

Commit 6bac2be

Browse files
smartycopemichaelmior
authored andcommitted
Added negative and * indecies and quotes to Split parameters
1 parent 519d97a commit 6bac2be

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

README.rst

+2
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ To use the extensions below you must import from `jsonpath_ng.ext`.
215215
| | - ``$.field.`sub(/regex/, replacement)``` |
216216
+--------------+-----------------------------------------------+
217217
| split | - ``$.field.`split(+, 2, -1)``` |
218+
| | - ``$.field.`split(",", *, -1)``` |
219+
| | - ``$.field.`split(' ', -1, -1)``` |
218220
| | - ``$.field.`split(sep, segement, maxsplit)```|
219221
+--------------+-----------------------------------------------+
220222
| sorted | - ``$.objects.`sorted``` |

jsonpath_ng/ext/string.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717

1818
SUB = re.compile(r"sub\(/(.*)/,\s+(.*)\)")
19-
SPLIT = re.compile(r"split\((.),\s+(\d+),\s+(\d+|-1)\)")
19+
SPLIT = re.compile(r"split(?:\s+)?\((?:\s+)?(?P<j>(?:(?:'|\"))?)(.+)(?P=j)(?:\s+)?,(?:\s+)?((?:(?:\-)?\d+|\*))(?:\s+)?,(?:\s+)?((?:\-)?\d+)(?:\s+)?\)")
2020
STR = re.compile(r"str\(\)")
2121

2222

@@ -60,23 +60,29 @@ def __str__(self):
6060
class Split(This):
6161
"""String splitter
6262
63-
Concrete syntax is '`split(char, segment, max_split)`'
63+
Concrete syntax is '`split(chars, segment, max_split)`'
64+
`chars` can optionally be surrounded by quotes, to specify things like commas or spaces
65+
`segment` can be `*` to select all
66+
`max_split` can be negative, to indicate no limit
6467
"""
6568

6669
def __init__(self, method=None):
6770
m = SPLIT.match(method)
6871
if m is None:
6972
raise DefintionInvalid("%s is not valid" % method)
70-
self.char = m.group(1)
71-
self.segment = int(m.group(2))
72-
self.max_split = int(m.group(3))
73+
self.chars = m.group(2)
74+
self.segment = m.group(3)
75+
self.max_split = int(m.group(4))
7376
self.method = method
7477

7578
def find(self, datum):
7679
datum = DatumInContext.wrap(datum)
7780
try:
78-
value = datum.value.split(self.char, self.max_split)[self.segment]
79-
except Exception:
81+
if self.segment == '*':
82+
value = datum.value.split(self.chars, self.max_split)
83+
else:
84+
value = datum.value.split(self.chars, self.max_split)[int(self.segment)]
85+
except:
8086
return []
8187
return [DatumInContext.wrap(value)]
8288

tests/test_jsonpath_rw_ext.py

+30
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,36 @@
400400
["cat-bow"],
401401
id="split2",
402402
),
403+
pytest.param(
404+
"payload.`split(',', 2, -1)`",
405+
{"payload": "foo,bar,baz"},
406+
["baz"],
407+
id="split3",
408+
),
409+
pytest.param(
410+
'payload.`split(", ", 2, -1)`',
411+
{"payload": "foo, bar, baz"},
412+
["baz"],
413+
id="split4",
414+
),
415+
pytest.param(
416+
'payload.`split(", ", *, -1)`',
417+
{"payload": "foo, bar, baz"},
418+
[["foo", "bar", "baz"]],
419+
id="split5",
420+
),
421+
pytest.param(
422+
'payload.`split(", ", -1, -1)`',
423+
{"payload": "foo, bar, baz"},
424+
["baz"],
425+
id="split6",
426+
),
427+
pytest.param(
428+
"payload.`split(|, -1, 1)`",
429+
{"payload": "foo|bar|baz"},
430+
["bar|baz"],
431+
id="split7",
432+
),
403433
pytest.param(
404434
"foo[?(@.baz==1)]",
405435
{"foo": [{"baz": 1}, {"baz": 2}]},

0 commit comments

Comments
 (0)