Cleaning. Normalise CRLF, strip ANSI escapes, backspaces and pager prompts (--More--,
---- More ----), convert tabs and dedent pasted text.
Prompt and echo extraction. If the first line is a prompt plus a command
(RP/0/RP0/CPU0:PE1#show bgp sum, lab@mx1> show route, <NE40E>display version), take the command and
hostname from it. Trailing bare prompts and {master} lines are dropped. A bare echoed command
(show bgp summary on the first line) also works. IOS XR timestamp lines go into metadata.timestamp.
Platform resolution. In order of precedence: the explicit argument, then the prompt, then detection
(command verb, weighted fingerprints such as interface naming, Junos table names and Huawei legend lines).
If detection is still ambiguous and a command is known, trial parsing runs every vendor's parser for
that command and keeps the richest result.
Structured short-cut.| display json / | display xml (or output that looks like JSON/XML) goes
straight to the structured engine.
Resolution. The command is split into a base command and | pipes. Filtering pipes add a warning. The
base is scored against every pattern registered for the platform.
Engines.native (dedicated parser), then ntc, genie, and finally generic. If a dedicated parser
raises, the failure is recorded as a warning and the next engine takes over (raise_on_error=True disables this).
Normalization. When asked, the parser's normalize() maps its native output to the vendor-neutral
schema.
Native output keeps vendor vocabulary. Nothing is thrown away, and field names are snake_case versions of
what the device prints. The normalized view sits alongside it rather than replacing it.
Flat lists with context tags instead of deep vendor hierarchies. For example, BGP neighbors are one list,
and each neighbor carries instance, vrf and address_family. This makes filtering and DataFrames easy.
Values are typed (int, float, bool, None) where that is unambiguous. Identifiers such as asdot ASNs
(65000.100), zero-padded IDs and interface names stay strings.
Per-line matching (textutils.match_lines) instead of multi-line regexes, so a short line can never
steal fields from the next one.
Zero dependencies. Optional features (YAML, pretty tables, TextFSM, Genie, SSH) are extras and are
detected at runtime.