file handling message for the userand returns false and no matter whatif the file was openedit is closed at the end parsing text using regular expressions |readers unfamiliar with regular expressions ("regexes"are recommended to read before reading this section--or to skip ahead to the following section )and return here later if desired using regular expressions to parse text files can often produce shorter code than doing everything by hand as we did in the previous subsectionbut it can be more difficult to provide good error reporting we will look at the import_text_regex(method in two partsfirst looking at the regular expressions and then at the parsing--but omitting the except and finally blocks since they have nothing new to teach us def import_text_regex(selffilename)incident_re re compiler"\[(? [^]]+)\](? +?) "^narrative_start$(? *?) "^narrative_end$"re dotall|re multilinekey_value_re re compile( "^\ *(? [^=]+?)\ *=\ * "(? +?)\ *$"re multilineraw strings the regular expressions are written as raw strings this saves us from having to double each backslash (writing each as \\)--for examplewithout using raw strings the second regular expression would have to be written as "^\\ *(? [^=]+?)\\ *=\\ *(? +?)\\ *$in this book we always use raw strings for regular expressions the first regular expressionincident_reis used to capture an entire incident record one effect of this is that any spurious text between records will not be noticed this regular expression really has two parts the first is \[(? [^]]+)\](? +?which matches [then matches and captures into the id match group as many non-characters as it canthen matches (so this gives us the report id)and then matches as few--but at least one--of any characters (including newlines because of the re dotall flag)into the keyvalues match group the characters matched for the keyvalues match group are the minimum necessary to take us to the second part of the regular expression the second part of the first regular expression is ^narrative_start(? *?)^narrative_endand this matches the literal text narrative_start then as few characters as possible which are captured into the narrative match groupand then the literal text narrative_end at the end of