Exercise 3 solution import re user_re = re.compile(r"[A-Za-z][A-Za-z0-9_]{2,15}") def check(s): return "ok" if user_re.fullmatch(s) else "invalid" for s in ["bob", "ab", "9lives", "good_name_1", "name with space", "a" * 17, "ok\n"]: print(repr(s[:12]), check(s)) # 'bob' ok # 'ab' invalid # '9lives' invalid # 'good_name_1' ok # 'name with sp' invalid # 'aaaaaaaaaaaa' invalid # 'ok\n' invalid print(bool(re.match(r"[A-Za-z]\w{2,15}$", "bob\n"))) # True (All lines were run and printed exactly what is shown.) Explanation: fullmatch rejects the trailing newline, but the "match with $" version accepts it, because $ also matches just before a final newline. That is why fullmatch is the safer choice for validation.