11from typing
import Tuple, Any, Dict, Set, List
13str_type: Tuple[type, ...] = (str, bytes)
14_generator_type = type((_
for _
in ()))
18 tup: Tuple[
"ParseResults", int]
21 def __init__(self, p1:
"ParseResults", p2: int):
22 self.
tuptup: Tuple[ParseResults, int] = (p1, p2)
35 """Structured parse results, to provide multiple means of access to
38 - as a list (``len(results)``)
39 - by list index (``results[0], results[1]``, etc.)
40 - by attribute (``results.<results_name>`` - see :class:`ParserElement.set_results_name`)
45 date_str = (integer.set_results_name("year") + '/'
46 + integer.set_results_name("month") + '/'
47 + integer.set_results_name("day"))
49 # date_str = (integer("year") + '/'
50 # + integer("month") + '/'
53 # parse_string returns a ParseResults object
54 result = date_str.parse_string("1999/12/31")
57 print(f"{s} -> {fn(eval(s))}")
60 test("result['month']")
62 test("'month' in result")
63 test("'minutes' in result")
64 test("result.dump()", str)
68 list(result) -> ['1999', '/', '12', '/', '31']
70 result['month'] -> '12'
72 'month' in result -> True
73 'minutes' in result -> False
74 result.dump() -> ['1999', '/', '12', '/', '31']
80 _null_values: Tuple[Any, ...] = (
None, [], ())
83 _parent:
"ParseResults"
87 _tokdict: Dict[str, Any]
100 Simple wrapper class to distinguish parsed list results that should be preserved
101 as actual Python lists, instead of being converted to :class:`ParseResults`::
103 LBRACK, RBRACK = map(pp.Suppress, "[]")
104 element = pp.Forward()
106 element_list = LBRACK + pp.DelimitedList(element) + RBRACK
108 # add parse actions to convert from ParseResults to actual Python collection types
109 def as_python_list(t):
110 return pp.ParseResults.List(t.as_list())
111 element_list.add_parse_action(as_python_list)
113 element <<= item | element_list
115 element.run_tests('''
121 ''', post_parse=lambda s, r: (r[0], type(r[0])))
129 ([2, 3, 4], <class 'list'>)
132 ([[2, 1], 3, 4], <class 'list'>)
134 (Used internally by :class:`Group` when `aslist=True`.)
138 if contained
is None:
143 f
"{cls.__name__} may only be constructed with a list, not {type(contained).__name__}"
148 def __new__(cls, toklist=None, name=None, **kwargs):
158 elif isinstance(toklist, (list, _generator_type)):
172 self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance
176 if name
is not None and name !=
"":
194 self[name]._name = name
197 self[name] = toklist[0]
198 except (KeyError, TypeError, IndexError):
199 if toklist
is not self:
244 for k, (value, position)
in enumerate(occurrences):
246 value, position - (position > j)
270 return (self[k]
for k
in self.
keys())
273 return ((k, self[k])
for k
in self.
keys())
277 Since ``keys()`` returns an iterator, this method is helpful in bypassing
278 code that looks for the existence of any defined results names."""
281 def pop(self, *args, **kwargs):
283 Removes and returns item at specified index (default= ``last``).
284 Supports both ``list`` and ``dict`` semantics for ``pop()``. If
285 passed no argument or an integer argument, it will use ``list``
286 semantics and pop tokens from the list of parsed tokens. If passed
287 a non-integer argument (most likely a string), it will use ``dict``
288 semantics and pop the corresponding value from any defined results
289 names. A second default return value argument is supported, just as in
294 numlist = Word(nums)[...]
295 print(numlist.parse_string("0 123 321")) # -> ['0', '123', '321']
297 def remove_first(tokens):
299 numlist.add_parse_action(remove_first)
300 print(numlist.parse_string("0 123 321")) # -> ['123', '321']
303 patt = label("LABEL") + Word(nums)[1, ...]
304 print(patt.parse_string("AAB 123 321").dump())
306 # Use pop() in a parse action to remove named result (note that corresponding value is not
307 # removed from list form of results)
308 def remove_LABEL(tokens):
311 patt.add_parse_action(remove_LABEL)
312 print(patt.parse_string("AAB 123 321").dump())
316 ['AAB', '123', '321']
319 ['AAB', '123', '321']
327 raise TypeError(f
"pop() got an unexpected keyword argument {k!r}")
328 if isinstance(args[0], int)
or len(args) == 1
or args[0]
in self:
334 defaultvalue = args[1]
337 def get(self, key, default_value=None):
339 Returns named result matching the given key, or if there is no
340 such name, then returns the given ``default_value`` or ``None`` if no
341 ``default_value`` is specified.
343 Similar to ``dict.get()``.
348 date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
350 result = date_str.parse_string("1999/12/31")
351 print(result.get("year")) # -> '1999'
352 print(result.get("hour", "not specified")) # -> 'not specified'
353 print(result.get("hour")) # -> None
362 Inserts new element at location index in the list of parsed tokens.
364 Similar to ``list.insert()``.
368 numlist = Word(nums)[...]
369 print(numlist.parse_string("0 123 321")) # -> ['0', '123', '321']
371 # use a parse action to insert the parse location in the front of the parsed results
372 def insert_locn(locn, tokens):
373 tokens.insert(0, locn)
374 numlist.add_parse_action(insert_locn)
375 print(numlist.parse_string("0 123 321")) # -> [0, '0', '123', '321']
380 for k, (value, position)
in enumerate(occurrences):
382 value, position + (position > index)
387 Add single element to end of ``ParseResults`` list of elements.
391 numlist = Word(nums)[...]
392 print(numlist.parse_string("0 123 321")) # -> ['0', '123', '321']
394 # use a parse action to compute the sum of the parsed integers, and add it to the end
395 def append_sum(tokens):
396 tokens.append(sum(map(int, tokens)))
397 numlist.add_parse_action(append_sum)
398 print(numlist.parse_string("0 123 321")) # -> ['0', '123', '321', 444]
404 Add sequence of elements to end of ``ParseResults`` list of elements.
408 patt = Word(alphas)[1, ...]
410 # use a parse action to append the reverse of the matched strings, to make a palindrome
411 def make_palindrome(tokens):
412 tokens.extend(reversed([t[::-1] for t in tokens]))
413 return ''.join(tokens)
414 patt.add_parse_action(make_palindrome)
415 print(patt.parse_string("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl'
424 Clear all elements and results names.
437 def __add__(self, other:
"ParseResults") ->
"ParseResults":
442 def __iadd__(self, other:
"ParseResults") ->
"ParseResults":
448 addoffset =
lambda a: offset
if a < 0
else a + offset
452 for k, vlist
in otheritems
455 for k, v
in otherdictitems:
473 return f
"{type(self).__name__}({self._toklist!r}, {self.as_dict()})"
480 str(i)
if isinstance(i, ParseResults)
else repr(i)
500 Returns the parse results as a nested list of matching tokens, all converted to strings.
504 patt = Word(alphas)[1, ...]
505 result = patt.parse_string("sldkj lsdkj sldkj")
506 # even though the result prints in string-like form, it is actually a pyparsing ParseResults
507 print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj']
509 # Use as_list() to create an actual list
510 result_list = result.as_list()
511 print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj']
520 Returns the named parse results as a nested dictionary.
525 date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
527 result = date_str.parse_string('12/31/1999')
528 print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]})
530 result_dict = result.as_dict()
531 print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'}
533 # even though a ParseResults supports dict-like access, sometime you just need to have a dict
535 print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable
536 print(json.dumps(result.as_dict())) # -> {"month": "31", "day": "1999", "year": "12"}
547 def copy(self) -> "ParseResults":
549 Returns a new shallow copy of a :class:`ParseResults` object. `ParseResults`
550 items contained within the source are shared with the copy. Use
551 :class:`ParseResults.deepcopy()` to create a copy with its own separate
561 def deepcopy(self) -> "ParseResults":
563 Returns a new deep copy of a :class:`ParseResults` object.
584 Returns the results name for this token expression. Useful when several
585 different expressions might match at a particular location.
590 ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d")
591 house_number_expr = Suppress('#') + Word(nums, alphanums)
592 user_data = (Group(house_number_expr)("house_number")
593 | Group(ssn_expr)("ssn")
594 | Group(integer)("age"))
595 user_info = user_data[1, ...]
597 result = user_info.parse_string("22 111-22-3333 #221B")
599 print(item.get_name(), ':', item[0])
615 for k, vlist
in parent_tokdict_items
630 def dump(self, indent="", full=True, include_list=True, _depth=0) -> str:
632 Diagnostic method for listing out the contents of
633 a :class:`ParseResults`. Accepts an optional ``indent`` argument so
634 that this string can be embedded in a nested display of other data.
639 date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
641 result = date_str.parse_string('1999/12/31')
646 ['1999', '/', '12', '/', '31']
657 items = sorted((str(k), v)
for k, v
in self.
items())
661 out.append(f
"{indent}{(' ' * _depth)}- {k}: ")
668 include_list=include_list,
681 "\n{}{}[{}]:\n{}{}{}".format(
686 (
" " * (_depth + 1)),
690 include_list=include_list,
697 "\n%s%s[%d]:\n%s%s%s"
703 (
" " * (_depth + 1)),
710 def pprint(self, *args, **kwargs):
712 Pretty-printer for parsed results as a list, using the
713 `pprint <https://docs.python.org/3/library/pprint.html>`_ module.
714 Accepts additional positional or keyword args as defined for
715 `pprint.pprint <https://docs.python.org/3/library/pprint.html#pprint.pprint>`_ .
719 ident = Word(alphas, alphanums)
722 term = ident | num | Group('(' + func + ')')
723 func <<= ident + Group(Optional(DelimitedList(term)))
724 result = func.parse_string("fna a,b,(fnb c,d,200),100")
725 result.pprint(width=40)
732 ['(', 'fnb', ['c', 'd', '200'], ')'],
758 return dir(type(self)) + list(self.
keys())
763 Helper classmethod to construct a ``ParseResults`` from a ``dict``, preserving the
764 name-value relations as results names. If an optional ``name`` argument is
765 given, a nested ``ParseResults`` will be returned.
784 ret =
cls([ret], name=name)
788 """Deprecated - use :class:`as_list`"""
790 """Deprecated - use :class:`as_dict`"""
792 """Deprecated - use :class:`get_name`"""
__new__(cls, contained=None)
"ParseResults" __iadd__(self, "ParseResults" other)
__init__(self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance)
_asStringList(self, sep="")
insert(self, index, ins_string)
__setitem__(self, k, v, isinstance=isinstance)
str dump(self, indent="", full=True, include_list=True, _depth=0)
__new__(cls, toklist=None, name=None, **kwargs)
"ParseResults" __add__(self, "ParseResults" other)
Iterator __reversed__(self)
pop(self, *args, **kwargs)
"ParseResults" __radd__(self, other)
"ParseResults" from_dict(cls, other, name=None)
"ParseResults" copy(self)
__setstate__(self, state)
bool __contains__(self, k)
__setstate__(self, *args)
__init__(self, "ParseResults" p1, int p2)