Exercise 3 solution import re expr = "a1+b2*(c-3)" parts = re.split(r"([+\-*/()])", expr) print(parts) # ['a1', '+', 'b2', '*', '', '(', 'c', '-', '3', ')', ''] print([p for p in parts if p]) # ['a1', '+', 'b2', '*', '(', 'c', '-', '3', ')'] doc = "Para one\nline two\n\n\nPara two\n\nPara three" paras = re.split(r"\n\s*\n", doc) print(paras, len(paras)) # ['Para one\nline two', 'Para two', 'Para three'] 3 print(re.split(r"\n\s*\n", doc, maxsplit=1)) # ['Para one\nline two', 'Para two\n\nPara three'] (All lines were run and printed exactly what is shown.) Explanation: a capturing group in the split pattern makes re.split keep the separators in the result. Two separators in a row ("*" then "(") leave an empty string between them, and a separator at the very end leaves one after it, so the list comprehension filters the empties out. The paragraph pattern \n\s*\n treats one or more blank lines as a single break. maxsplit=1 stops after the first break.