L'itération sur des chaînes est malheureusement assez lente en Python. Les expressions régulières sont plus rapides d'un ordre de grandeur pour ce genre de chose. Il vous suffit de créer vous-même la classe de personnage. Le module unicodedata est très utile pour cela, en particulier la fonction unicodedata.category () . Voir Base de données de caractères Unicode pour une description des catégories.
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)
Pour 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)
Pour certains cas d'utilisation, des catégories supplémentaires (par exemple, toutes du groupe témoin peuvent être préférables, bien que cela puisse ralentir le temps de traitement et augmenter considérablement l'utilisation de la mémoire. Nombre de caractères par catégorie:
Cc
(contrôle): 65
Cf
(format): 161
Cs
(substitut): 2048
Co
(à usage privé): 137468
Cn
(non attribué): 836601
Modifier Ajout de suggestions à partir des commentaires.
all_chars = (unichr(i) for i in xrange(sys.maxunicode))
pour éviter l'erreur de construction étroite.control_chars == '\x00-\x1f\x7f-\x9f'
(testé sur Python 3.5.2)Autant que je sache, la méthode la plus pythonique / efficace serait:
la source
Vous pouvez essayer de configurer un filtre en utilisant la
unicodedata.category()
fonction:Reportez-vous au Tableau 4-9 à la page 175 dans les propriétés des caractères de la base de données Unicode pour les catégories disponibles
la source
printable = {'Lu', 'Ll', Zs', 'Nd'}
Dans Python 3,
Voir cet article de StackOverflow sur la suppression de la ponctuation pour savoir comment .translate () se compare à regex et .replace ()
Les plages peuvent être générées en
nonprintable = (ord(c) for c in (chr(i) for i in range(sys.maxunicode)) if unicodedata.category(c)=='Cc')
utilisant les catégories de base de données de caractères Unicode comme indiqué par @Ants Aasma.la source
text.translate({c:None for c in itertools.chain(range(0x00,0x20),range(0x7f,0xa0))})
.Ce qui suit fonctionnera avec l'entrée Unicode et est plutôt rapide ...
Mes propres tests suggèrent que cette approche est plus rapide que les fonctions qui itèrent sur la chaîne et retournent un résultat en utilisant
str.join
.la source
LINE_BREAK_CHARACTERS = set(["\n", "\r"])
etand not chr(i) in LINE_BREAK_CHARACTERS
lors de la création du tableau.Cette fonction utilise des compréhensions de liste et str.join, donc elle s'exécute en temps linéaire au lieu de O (n ^ 2):
la source
filter(isprint,input)
Encore une autre option dans python 3:
la source
r'[^' + re.escape(string.printable) + r']'
. (Je ne pense pas que cere.escape()
soit tout à fait correct ici, mais si cela fonctionne ...)Le meilleur que j'ai trouvé maintenant est (grâce aux python-izers ci-dessus)
C'est le seul moyen que j'ai découvert qui fonctionne avec les caractères / chaînes Unicode
Y a-t-il de meilleures options?
la source
Celui ci-dessous fonctionne plus rapidement que les autres ci-dessus. Regarde
la source
"".join([c if 0x21<=ord(c) and ord(c)<=0x7e else "" for c in ss])
Il y en a lors de l'utilisation de la
regex
bibliothèque: https://pypi.org/project/regex/Il est bien entretenu et prend en charge les expressions régulières Unicode, Posix regex et bien d'autres. L'utilisation (signatures de méthode) est très similaire à celle de Python
re
.De la documentation:
(Je ne suis pas affilié, juste un utilisateur.)
la source
Sur la base de la réponse de @ Ber, je suggère de supprimer uniquement les caractères de contrôle tels que définis dans les catégories de la base de données de caractères Unicode :
la source
Pour supprimer les «espaces»,
la source
Adapté des réponses d' Ants Aasma et shawnrad :
testé sur Python 3.7.7
la source