PythiloLesson 10 of 15 · progress kept in this browser

Searching text with re

A regular expression is a small pattern language for text. It is the tool behind grep, search and replace in editors, and most log analysis, and Python's re module runs the same patterns.

import re

line = "08:15:02 ERROR [db] timeout 30s"
entry = re.compile(
    r"(?P<time>\d\d:\d\d:\d\d) "
    r"(?P<level>[A-Z]+) "
    r"\[(?P<part>[^\]]+)\]")
m = entry.match(line)
print(m["level"], m["part"])
print(re.findall(r"\d+", line))
  • \d is a digit and [A-Z] one capital letter. + means one or more, and [^\]] is any character except ].
  • Characters such as [, . and ( have special meanings, so a backslash makes them literal: \[.
  • Write patterns as raw strings, r"...", so backslashes reach re untouched.
  • match anchors at the start, search looks anywhere, and findall returns every match.
  • (?P<name>...) names a group, and m["name"] reads it back.

When the text does not fit, match returns None, so test the result before using it.

Your task

Write error_counts(text) that reads a log with one entry per line, in the form HH:MM:SS LEVEL [component] message, and returns a dict counting the ERROR entries for each component. Skip lines that are not in that form.