A iteração em strings é, infelizmente, bastante lenta em Python. As expressões regulares são mais do que uma ordem de magnitude mais rápidas para esse tipo de coisa. Você apenas tem que construir a classe de personagem sozinho. O módulo unicodedata é bastante útil para isso, especialmente a função unicodedata.category () . Consulte o banco de dados de caracteres Unicode para obter as descrições das categorias.
import unicodedata, re, itertools, sys
all_chars = (chr(i) for i in range(sys.maxunicode))
categories = {'Cc'}
control_chars = ''.join(c for c in all_chars if unicodedata.category(c) in categories)
# or equivalently and much more efficiently
control_chars = ''.join(map(chr, itertools.chain(range(0x00,0x20), range(0x7f,0xa0))))
control_char_re = re.compile('[%s]' % re.escape(control_chars))
def remove_control_chars(s):
return control_char_re.sub('', s)
Para Python2
import unicodedata, re, sys
all_chars = (unichr(i) for i in xrange(sys.maxunicode))
categories = {'Cc'}
control_chars = ''.join(c for c in all_chars if unicodedata.category(c) in categories)
# or equivalently and much more efficiently
control_chars = ''.join(map(unichr, range(0x00,0x20) + range(0x7f,0xa0)))
control_char_re = re.compile('[%s]' % re.escape(control_chars))
def remove_control_chars(s):
return control_char_re.sub('', s)
Para alguns casos de uso, categorias adicionais (por exemplo, todas do grupo de controle podem ser preferíveis, embora isso possa diminuir o tempo de processamento e aumentar o uso de memória significativamente. Número de caracteres por categoria:
Cc
(controle): 65
Cf
(formato): 161
Cs
(substituto): 2048
Co
(uso privado): 137468
Cn
(não atribuído): 836601
Editar Adicionando sugestões dos comentários.