class ParseResults: """Structured parse results, to provide multiple means of access to
the parsed data:
- as a list (``len(results)``)
- by list index (``results[0], results[1]``, etc.)
- by attribute (``results.<results_name>`` - see :class:`ParserElement.set_results_name`)
class List(list): """
Simple wrapper class to distinguish parsed list results that should be preserved as actual Python lists, instead of being converted to :class:`ParseResults`::
# add parse actions to convert from ParseResults to actual Python collection types def as_python_list(t): return pp.ParseResults.List(t.as_list())
element_list.add_parse_action(as_python_list)
# Performance tuning: we construct a *lot* of these, so keep this # constructor as small and fast as possible def __init__(
self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance
):
self._tokdict: Dict[str, _ParseResultsWithOffset]
self._modal = modal if name isnotNoneand name != "": if isinstance(name, int):
name = str(name) ifnot modal:
self._all_names = {name}
self._name = name if toklist notin self._null_values: if isinstance(toklist, (str_type, type)):
toklist = [toklist] if asList: if isinstance(toklist, ParseResults):
self[name] = _ParseResultsWithOffset(
ParseResults(toklist._toklist), 0
) else:
self[name] = _ParseResultsWithOffset(
ParseResults(toklist[0]), 0
)
self[name]._name = name else: try:
self[name] = toklist[0] except (KeyError, TypeError, IndexError): if toklist isnot self:
self[name] = toklist else:
self._name = name
def __getitem__(self, i): if isinstance(i, (int, slice)): return self._toklist[i] else: if i notin self._all_names: return self._tokdict[i][-1][0] else: return ParseResults([v[0] for v in self._tokdict[i]])
def __setitem__(self, k, v, isinstance=isinstance): if isinstance(v, _ParseResultsWithOffset):
self._tokdict[k] = self._tokdict.get(k, list()) + [v]
sub = v[0] elif isinstance(k, (int, slice)):
self._toklist[k] = v
sub = v else:
self._tokdict[k] = self._tokdict.get(k, list()) + [
_ParseResultsWithOffset(v, 0)
]
sub = v if isinstance(sub, ParseResults):
sub._parent = self
def __delitem__(self, i): if isinstance(i, (int, slice)):
mylen = len(self._toklist) del self._toklist[i]
# convert int to slice if isinstance(i, int): if i < 0:
i += mylen
i = slice(i, i + 1) # get removed indices
removed = list(range(*i.indices(mylen)))
removed.reverse() # fixup indices in token dictionary for name, occurrences in self._tokdict.items(): for j in removed: for k, (value, position) in enumerate(occurrences):
occurrences[k] = _ParseResultsWithOffset(
value, position - (position > j)
) else: del self._tokdict[i]
def __contains__(self, k) -> bool: return k in self._tokdict
def values(self): return (self[k] for k in self.keys())
def items(self): return ((k, self[k]) for k in self.keys())
def haskeys(self) -> bool: """
Since ``keys()`` returns an iterator, this method is helpful in bypassing
code that looks for the existence of any defined results names.""" returnnotnot self._tokdict
def pop(self, *args, **kwargs): """
Removes and returns item at specified index (default= ``last``).
Supports both ``list`` and ``dict`` semantics for ``pop()``. If
passed no argument or an integer argument, it will use ``list``
semantics and pop tokens from the list of parsed tokens. If passed
a non-integer argument (most likely a string), it will use ``dict``
semantics and pop the corresponding value from any defined results
names. A second default return value argument is supported, just asin
``dict.pop()``.
# Use pop() in a parse action to remove named result (note that corresponding value is not # removed from list form of results) def remove_LABEL(tokens):
tokens.pop("LABEL") return tokens
patt.add_parse_action(remove_LABEL)
print(patt.parse_string("AAB 123 321").dump())
prints::
['AAB', '123', '321']
- LABEL: 'AAB'
['AAB', '123', '321'] """ ifnot args:
args = [-1] for k, v in kwargs.items(): if k == "default":
args = (args[0], v) else: raise TypeError(f"pop() got an unexpected keyword argument {k!r}") if isinstance(args[0], int) or len(args) == 1 or args[0] in self:
index = args[0]
ret = self[index] del self[index] return ret else:
defaultvalue = args[1] return defaultvalue
def get(self, key, default_value=None): """
Returns named result matching the given key, orif there is no
such name, then returns the given ``default_value`` or ``None`` if no
``default_value`` is specified.
# use a parse action to insert the parse location in the front of the parsed results def insert_locn(locn, tokens):
tokens.insert(0, locn)
numlist.add_parse_action(insert_locn)
print(numlist.parse_string("0 123 321")) # -> [0, '0', '123', '321'] """
self._toklist.insert(index, ins_string) # fixup indices in token dictionary for name, occurrences in self._tokdict.items(): for k, (value, position) in enumerate(occurrences):
occurrences[k] = _ParseResultsWithOffset(
value, position + (position > index)
)
def append(self, item): """
Add single element to end of ``ParseResults`` list of elements.
# use a parse action to compute the sum of the parsed integers, and add it to the end def append_sum(tokens):
tokens.append(sum(map(int, tokens)))
numlist.add_parse_action(append_sum)
print(numlist.parse_string("0 123 321")) # -> ['0', '123', '321', 444] """
self._toklist.append(item)
def extend(self, itemseq): """
Add sequence of elements to end of ``ParseResults`` list of elements.
Example::
patt = Word(alphas)[1, ...]
# use a parse action to append the reverse of the matched strings, to make a palindrome def make_palindrome(tokens):
tokens.extend(reversed([t[::-1] for t in tokens])) return''.join(tokens)
patt.add_parse_action(make_palindrome)
print(patt.parse_string("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' """ if isinstance(itemseq, ParseResults):
self.__iadd__(itemseq) else:
self._toklist.extend(itemseq)
def clear(self): """
Clear all elements and results names. """ del self._toklist[:]
self._tokdict.clear()
if other._tokdict:
offset = len(self._toklist)
addoffset = lambda a: offset if a < 0 else a + offset
otheritems = other._tokdict.items()
otherdictitems = [
(k, _ParseResultsWithOffset(v[0], addoffset(v[1]))) for k, vlist in otheritems for v in vlist
] for k, v in otherdictitems:
self[k] = v if isinstance(v[0], ParseResults):
v[0]._parent = self
def __radd__(self, other) -> "ParseResults": if isinstance(other, int) and other == 0: # useful for merging many ParseResults using sum() builtin return self.copy() else: # this may raise a TypeError - so be it return other + self
def __str__(self) -> str: return ( "["
+ ", ".join(
[
str(i) if isinstance(i, ParseResults) else repr(i) for i in self._toklist
]
)
+ "]"
)
def _asStringList(self, sep=""):
out = [] for item in self._toklist: if out and sep:
out.append(sep) if isinstance(item, ParseResults):
out += item._asStringList() else:
out.append(str(item)) return out
def as_list(self) -> list: """
Returns the parse results as a nested list of matching tokens, all converted to strings.
Example::
patt = Word(alphas)[1, ...]
result = patt.parse_string("sldkj lsdkj sldkj") # even though the result prints in string-like form, it is actually a pyparsing ParseResults
print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj']
# Use as_list() to create an actual list
result_list = result.as_list()
print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj'] """ return [
res.as_list() if isinstance(res, ParseResults) else res for res in self._toklist
]
def as_dict(self) -> dict: """
Returns the named parse results as a nested dictionary.
# even though a ParseResults supports dict-like access, sometime you just need to have a dict import json
print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable
print(json.dumps(result.as_dict())) # -> {"month": "31", "day": "1999", "year": "12"} """
def to_item(obj): if isinstance(obj, ParseResults): return obj.as_dict() if obj.haskeys() else [to_item(v) for v in obj] else: return obj
return dict((k, to_item(v)) for k, v in self.items())
def copy(self) -> "ParseResults": """
Returns a new shallow copy of a :class:`ParseResults` object. `ParseResults`
items contained within the source are shared with the copy. Use
:class:`ParseResults.deepcopy()` to create a copy with its own separate
content values. """
ret = ParseResults(self._toklist)
ret._tokdict = self._tokdict.copy()
ret._parent = self._parent
ret._all_names |= self._all_names
ret._name = self._name return ret
def deepcopy(self) -> "ParseResults": """
Returns a new deep copy of a :class:`ParseResults` object. """
ret = self.copy() # replace values with copies if they are of known mutable types for i, obj in enumerate(self._toklist): if isinstance(obj, ParseResults):
self._toklist[i] = obj.deepcopy() elif isinstance(obj, (str, bytes)): pass elif isinstance(obj, MutableMapping):
self._toklist[i] = dest = type(obj)() for k, v in obj.items():
dest[k] = v.deepcopy() if isinstance(v, ParseResults) else v elif isinstance(obj, Container):
self._toklist[i] = type(obj)(
v.deepcopy() if isinstance(v, ParseResults) else v for v in obj
) return ret
def get_name(self):
r"""
Returns the results name for this token expression. Useful when several
different expressions might match at a particular location.
result = user_info.parse_string("22 111-22-3333 #221B") for item in result:
print(item.get_name(), ':', item[0])
prints::
age : 22
ssn : 111-22-3333
house_number : 221B """ if self._name: return self._name elif self._parent:
par: "ParseResults" = self._parent
parent_tokdict_items = par._tokdict.items() return next(
(
k for k, vlist in parent_tokdict_items for v, loc in vlist if v is self
), None,
) elif (
len(self) == 1 and len(self._tokdict) == 1 and next(iter(self._tokdict.values()))[0][1] in (0, -1)
): return next(iter(self._tokdict.keys())) else: returnNone
def dump(self, indent="", full=True, include_list=True, _depth=0) -> str: """
Diagnostic method for listing out the contents of
a :class:`ParseResults`. Accepts an optional ``indent`` argument so
that this string can be embedded in a nested display of other data.
@classmethod def from_dict(cls, other, name=None) -> "ParseResults": """
Helper classmethod to construct a ``ParseResults`` from a ``dict``, preserving the
name-value relations as results names. If an optional ``name`` argument is
given, a nested ``ParseResults`` will be returned. """
def is_iterable(obj): try:
iter(obj) except Exception: returnFalse # str's are iterable, but in pyparsing, we don't want to iterate over them else: returnnot isinstance(obj, str_type)
ret = cls([]) for k, v in other.items(): if isinstance(v, Mapping):
ret += cls.from_dict(v, name=k) else:
ret += cls([v], name=k, asList=is_iterable(v)) if name isnotNone:
ret = cls([ret], name=name) return ret
asList = as_list """Deprecated - use :class:`as_list`"""
asDict = as_dict """Deprecated - use :class:`as_dict`"""
getName = get_name """Deprecated - use :class:`get_name`"""
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.