When I have a string like this:
s1 = 'stuff(remove_me)'
# returns 'stuff'
res1 = re.sub(r'\([^)]*\)', '', s1)
s2 = 'stuff(remove(me))'
re.sub('\(.*?\)', '', s2)
re matches are eager so they try to match as much text as possible, for the simple test case you mention just let the regex run:
>>> re.sub(r'\(.*\)', '', 'stuff(remove(me))') 'stuff'