Exercise 3 solution import re lines = [ "10:00 user=ann ip=10.0.0.5 action=login", "10:01 user=bob ip=192.168.1.20 action=logout", "10:02 action=ping", ] for l in lines: print(re.sub(r"(ip=)\d{1,3}(?:\.\d{1,3}){3}", r"\1x.x.x.x", l)) # 10:00 user=ann ip=x.x.x.x action=login # 10:01 user=bob ip=x.x.x.x action=logout # 10:02 action=ping (All lines were run and printed exactly what is shown.) Explanation: group 1 captures the literal "ip=", and \1 in the replacement puts it back, so only the address is replaced. The address itself is matched by a non-capturing group repeated three times after the first number. A line with no "ip=" has no match, so re.sub returns it unchanged.