Exercise 3 solution import re urls = "http://a.com/x https://b.org/y/z ftp://c.net" print(re.findall(r"(https?)://([\w.]+)", urls)) # [('http', 'a.com'), ('https', 'b.org')] print(re.findall(r"(?:https?)://([\w.]+)", urls)) # ['a.com', 'b.org'] print(re.findall(r"(?Phttps?)://(?P[\w.]+)", urls)) # [('http', 'a.com'), ('https', 'b.org')] for m in re.finditer(r"(?Phttps?)://(?P[\w.]+)", urls): print(m.groupdict()) # {'proto': 'http', 'host': 'a.com'} # {'proto': 'https', 'host': 'b.org'} (All lines were run and printed exactly the output shown.) Explanation: findall returns tuples when there are two or more capturing groups, and plain strings when there is exactly one. Making the protocol group non-capturing leaves a single group, so only the host is returned. Naming the groups does not change what findall returns, but finditer with groupdict() gives each match as a labelled dictionary. The ftp address is skipped in every case because the pattern only allows http or https.