Znaki Unicode z zakresów \u0000-\uD7FF i \uE000-\uFFFF będą miały kodowanie 3 bajtowe (lub mniej) w UTF8. Zakres \uD800-\uDFFF dotyczy wielobajtowego UTF16. Nie znam pythona, ale powinieneś być w stanie ustawić wyrażenie regularne, aby pasowało poza tymi zakresami.
pattern = re.compile("[\uD800-\uDFFF].", re.UNICODE)
pattern = re.compile("[^\u0000-\uFFFF]", re.UNICODE)
Edytuj dodawanie Pythona ze skryptu Denilsona Sá w treści pytania:
re_pattern = re.compile(u'[^\u0000-\uD7FF\uE000-\uFFFF]', re.UNICODE)
filtered_string = re_pattern.sub(u'\uFFFD', unicode_string)