Exercise 3 solution import re q = re.compile(r"'([^']*)'|\"([^\"]*)\"|(\S+)") s = """say 'hello world' to "big wide" world""" words = [next(g for g in m.groups() if g is not None) for m in q.finditer(s)] print(words) # ['say', 'hello world', 'to', 'big wide', 'world'] (All lines were run and printed exactly what is shown.) Explanation: the pattern has three alternatives with one group each: single quoted text, double quoted text, and a bare word. Only the group of the alternative that matched is not None, so next(...) picks it out. Quoted alternatives come before \S+ so that a quote mark starts a phrase instead of a plain word. Note that a quoted empty string ('') would give '' which is not None, so it is still kept correctly; that is why the test is "is not None" and not simply "truthy".