Вы также можете использовать простой подход: сопоставить и захватить то, что вам нужно, чтобы «исключить» из сопоставления и просто сопоставить то, что вы хотите удалить, а затем просто использовать обратную ссылку на значение группы захвата:
re.sub(r'([#@\s]|:[)(])|\W', r'\1', s)
# ^---Group 1--^->->->->^^
См. Демоверсию regex .
Здесь ([#@\s]|:[)(])
соответствует и захватывает в Группу 1 a #
, @
, пробельные символы или :(
или :(
подстроки и \W
совпадения без захвата любого несловарного символа.
См. Демо Python :
import re
s="this is, a placeholder text. I wanna remove symbols like ! and ? but keep @ & # & :)"
print(re.sub(r'([#@\s]|:[)(])|\W', r'\1', s))
# => this is a placeholder text I wanna remove symbols like and but keep @ # :)
В версиях Python до 3.5 используйте лямбда-выражение в качестве аргумента замены (из-за ошибки):
re.sub(r'([#@\s]|:[)(])|\W', lambda x: x.group(1) if x.group(1) else '', s)