ну шоб чисто через одну re, то тут ХЗ, а так вообще можно, если использовать ре, лямбду и словарь.
import re
text = "a+(b+c)*a-b"
dct = {
"a" : "1",
"b" : "2",
"c" : "3",
}
print(re.sub('({})'.format("|".join(map(re.escape, dct.keys()))), lambda x: dct[x.string[x.start():x.end()]], text))
>>>
1+(2+3)*1-2
>>>
кажеться весьма сложно и непонятно, для простоты понимания, можно упростить для конкретного примера.
print(re.sub('(a|b|c)', lambda x: {'a': '1', 'c': '3', 'b': '2'}[x.group()] , text))
>>>
1+(2+3)*1-2
>>>
оригинал решения тут
https://code.activestate.com/recipes/81330-single-pass-multiple-replace/Оно конечно не идеально, там есть свои недостаки и нюансы, но в данном случае подходит.