Это проблема, которую, вероятно, может полностью решить только синтаксический анализатор языка, но вы можете сделать аппроксимацию, сначала сопоставив все, что вы не хотите, а затем захватывая только то, что вы хотите поочередно. Например:
r='"{3}.*?"{3}|#[^"\'\n]*|source ([^\n#]*)'
См. regex demo .
Пример кода:
regex = r'"{3}.*?\"{3}|#[^"\'\n]*|source ([^\n#]*)'
matches = re.findall(regex, your_text, re.MULTILINE)
print(matches)
Выход:
['run.sh', '/path/run3.sh ', '', './run4.changelist', './run4.changelist',
'run.changelist', '', './run4.changelist', '', '', '', '', '', '', '']
Теперь вам придется действовать со всеми непустыми захватами либо фильтрованием, либо итерацией, и т. Д. c.
Редактировать: Мне, вероятно, следовало добавить пример фильтра:
filter(lambda c: c != '', matches)