Ваш образец текста содержит много пробелов, в том числе после обратной косой черты. Я предполагаю, что это не то, что вы намеревались, поскольку цель обратной косой черты заключается в том, чтобы избежать перевода строки, который обычно отмечал бы конец записи.
Но обратные слэши могут использоваться и для экранирования других персонажей, включая обратные слэши. Если значение заканчивается обратной косой чертой, оно будет отображаться как две обратной косой черты в make-файле. Взгляд в вашем регулярном выражении «увидит» второе и неправильно воспримет его как продолжение строки.
Если вы думаете добавить еще один вид сзади, чтобы увидеть, не произошла ли обратная косая черта, позвольте мне остановить вас сейчас. Это многократно хешировалось, и подход за кадром нельзя заставить работать. То, что вы хотите, это что-то вроде этого:
regex = re.compile(r'^FOO=([^\n\\]*(?:\\.[^\n\\]*)*)$', re.M | re.S)
См. Это в действии на ideone
Первый [^\n\\]*
потребляет столько символов без перевода строки, без обратной косой черты, сколько может, затем передает управление следующей части. Если конец строки не был достигнут, он пытается сопоставить обратную косую черту, за которой следует любой символ (включая перевод строки, благодаря модификатору re.S
), за которым следуют мои более «нормальные» символы. Так продолжается в цикле до тех пор, пока (при условии, что вход действителен), он не попадет в неэкранированный перевод строки или в конец ввода.
Хотя это модификатор re.S
, который позволяет точкам соответствовать новые строки, модификатор re.M
также необходим; это то, что позволяет ^
соответствовать началу строки, а $
соответствует концу строки, как объяснила @stema.