Вы получаете только первую группу захвата, потому что вы соответствуете .*?
, которое не является жадным, и затем захватываете в группе, совпадающей ноль или более раз, символ слова или точку [\w\.]*
, за которыми следует либо Исключение, либо Ошибка.Первое совпадение - RecoverableBuildException
, и захватывается группа 1.
Далее следует (: .*?\n)?
, но после сопоставления с первой группой не существует совпадения :
, поэтому вторая группа не совпадает.
Вы можете использовать ::
Traceback \(most recent call last\):(?:\n.*)+?\n(.*?(?:Exception|Error):)\s*(.+)
Regex demo
Это будет соответствовать:
Traceback \(most recent call last\):
Соответствовать буквально (?:\n.*)+?
Повторить для группы без захвата, соответствующей символу новой строки, за которым 0+ раз вводится любой символ \n(.*?(?:Exception|Error):) Match newline and capturinggroup 0+ characters non greedy and than match Exception of Error followed by
: ` \s*
Совпадение 0+ пробельных символов (.+)
Захват группы 1+ раз любого символа
Например:
EXCEPTION_PATTERN = re.compile(
r"Traceback \(most recent call last\):(?:\n.*)+?\n(.*?(?:Exception|Error):)\s*(.+)"
)
ex_match = EXCEPTION_PATTERN.findall(st)
print(ex_match) # [('common.exceptions.BuildException:', 'test error')]