Parsing device output and logs with Python regular expressions
In short: Regular expressions describe text patterns. With the re module you can capture fields such as interface names and IP addresses from show commands and logs, then store them as dictionaries. Use raw strings, named groups and tested sample data, and reach for TextFSM or Genie templates for common commands.
Why parse text at all
Many devices still answer in human-friendly text. To act on that output, a script needs it as data: which interfaces are down, which neighbours exist, how many errors a port has. A regular expression (regex) is a compact pattern language for finding and capturing parts of text. Python’s built-in re module provides it.
Core regex tokens
Always write patterns as raw strings (r"...") so Python does not treat backslashes as its own escape codes. Use re.search() to find the first match anywhere, re.match() to match only at the start, and re.finditer() to loop over every match. Named groups, written (?P<name>...), let you read results by name with m["name"].
import re
output = """Interface IP-Address OK? Method Status Protocol
GigabitEthernet0/0 192.168.10.1 YES manual up up
GigabitEthernet0/1 unassigned YES unset administratively down down
Loopback0 10.255.0.1 YES manual up up"""
pattern = re.compile(
r"^(?P<intf>\S+)\s+(?P<ip>\S+)\s+\w+\s+\w+\s+"
r"(?P<status>up|down|administratively down)\s+(?P<proto>up|down)$",
re.MULTILINE,
)
interfaces = [m.groupdict() for m in pattern.finditer(output)]
for i in interfaces:
print(i["intf"], i["ip"], i["status"])
down = [i["intf"] for i in interfaces if i["proto"] != "up"]
print("Down:", down)
re.MULTILINE makes ^ and $ match at the start and end of every line, not only the whole string. The header line does not match, so it is skipped automatically.
Parsing logs
Syslog messages have a fairly regular shape, which makes them good regex targets. This example counts interface state changes per interface from a log file.
import re
from collections import Counter
log_re = re.compile(
r"%LINEPROTO-5-UPDOWN: Line protocol on Interface (?P<intf>\S+), "
r"changed state to (?P<state>up|down)"
)
flaps = Counter()
with open("syslog.txt", encoding="utf-8") as f:
for line in f:
m = log_re.search(line)
if m:
flaps[m["intf"]] += 1
for intf, count in flaps.most_common(5):
print(intf, count)
Tip: build patterns against real sample output saved in a file, and test them before trusting them. An online tester is fine for learning, but never paste confidential logs into third-party websites.
Pitfalls and better alternatives
- Greedy matching:
.*grabs as much as possible. Prefer specific tokens such as\S+, or the lazy form.*?. - Escape special characters: a literal dot in an address is
\.. Better still, capture\S+and check it with the ipaddress module. - Fragile patterns: output changes between software versions. Fail loudly when nothing matches instead of silently reporting "no problems".
- Slow patterns: nested repeats such as
(a+)+can take exponential time on some input (ReDoS, regular expression denial of service). Keep patterns simple, especially on input from untrusted sources.
| Approach | Best for |
|---|---|
| Your own regex | Logs, one-off or unusual output |
| TextFSM templates (for example the ntc-templates collection) | Common show commands across many vendors |
| Cisco Genie/pyATS parsers | Detailed Cisco output |
| Structured APIs (NETCONF, RESTCONF, JSON output) | Avoiding screen scraping altogether |
Netmiko can call TextFSM for you with use_textfsm=True. When a device offers structured output, use it: parsing text should be a fallback, not the plan.
Practice
Why should regex patterns be written as raw strings in Python?
What does re.MULTILINE change?
Your parser finds zero down interfaces after a software upgrade. What should you suspect?
Key takeaways
- Use the re module with raw strings and compiled patterns.
- Named groups and groupdict() turn matches into dictionaries.
- re.MULTILINE is needed for line-based device output.
- Prefer specific tokens over greedy .* and keep patterns simple to avoid ReDoS.
- Use TextFSM, Genie or structured APIs where they exist.
Original content written by Mohamed Fayas for FM TecHub. © 2026 FM TecHub. You're welcome to share a link to this page; please don't copy the text elsewhere without permission.