Ваше регулярное выражение и замена требуют нескольких настроек.
r = re.compile(r"(\*[^ ]+\*)")
Здесь вы снимаете слишком много - звездочки сохраняются в \1
.
r.sub(r'<i>"\1"</i>', foo)
Вы подставляете здесь слишком много - двойные кавычки включены в подстановку. Пример:
r.sub(r'<i>"\1"</i>', '*foo*') # -> '<i>"*foo*"</i>'
Попробуйте что-то вроде этого:
foo = '***foo***'
bold = re.compile(r'''\*\*([^ ]+)\*\*''')
ital = re.compile(r'''\*([^ ]+)\*''')
ital.sub(r'''<i>\1</i>''', bold.sub(r'''<b>\1</b>''', foo)) # '<b><i>foo</i></b>'