Je dois remplacer tous les caractères non ASCII (\ x00- \ x7F) par un espace. Je suis surpris que ce ne soit pas facile à faire en Python, sauf si je manque quelque chose. La fonction suivante supprime simplement tous les caractères non ASCII:
def remove_non_ascii_1(text):
return ''.join(i for i in text if ord(i)<128)
Et celui-ci remplace les caractères non ASCII par la quantité d'espaces selon la quantité d'octets dans le point de code de caractère (c'est-à-dire que le –
caractère est remplacé par 3 espaces):
def remove_non_ascii_2(text):
return re.sub(r'[^\x00-\x7F]',' ', text)
Comment remplacer tous les caractères non ASCII par un seul espace?
Parmi la myriade de questions SO similaires , aucune ne concerne le remplacement de caractère par opposition à la suppression , et traite également tous les caractères non-ascii et non un caractère spécifique.
–
. C'est ce mec .Réponses:
Votre
''.join()
expression filtre , supprimant tout ce qui n'est pas ASCII; vous pouvez utiliser une expression conditionnelle à la place:Cela gère les caractères un par un et utilise toujours un espace par caractère remplacé.
Votre expression régulière doit simplement remplacer les caractères non ASCII consécutifs par un espace:
Notez le
+
là.la source
str.join()
a besoin d' une liste (elle passera deux fois sur les valeurs), et une expression de générateur sera d'abord convertie en une. Lui donner une liste de compréhension est tout simplement plus rapide. Voir cet article .–
caractère est remplacé par 3 espaces" dans la question implique que l'entrée est un bytestring (pas Unicode) et donc Python 2 est utilisé (sinon''.join
échouerait). Si OP souhaite un seul espace par point de code Unicode, l'entrée doit d'abord être décodée en Unicode.Pour vous obtenir la représentation la plus similaire de votre chaîne d'origine, je recommande le module unidecode :
Ensuite, vous pouvez l'utiliser dans une chaîne:
la source
דותן
. Cependant, dans le sens général, c'est super, merci!Pour le traitement des caractères , utilisez des chaînes Unicode:
Mais notez que vous aurez toujours un problème si votre chaîne contient des caractères Unicode décomposés (caractère séparé et combinaison de marques d'accentuation, par exemple):
la source
ud.normalize('NFC',s)
pour combiner des marques, mais toutes les combinaisons de combinaisons ne sont pas représentées par des points de code uniques. Vous auriez besoin d'une solution plus intelligente en regardantud.category()
le personnage.\X
(eXtended grapheme cluster) regex (pris en charge par leregex
module) permet d'itérer sur de tels caractères (note: "les graphèmes ne combinent pas nécessairement des séquences de caractères, et la combinaison de séquences de caractères ne sont pas nécessairement des graphèmes" ).Si le caractère de remplacement peut être «?» au lieu d'un espace, alors je suggère
result = text.encode('ascii', 'replace').decode()
:Résultats:
la source
Et celui-ci?
la source
En tant qu'approche native et efficace, vous n'avez pas besoin d'utiliser
ord
ou de boucle sur les personnages. Il suffit d'encoderascii
et d'ignorer les erreurs.Ce qui suit supprimera simplement les caractères non ascii:
Maintenant, si vous souhaitez remplacer les caractères supprimés, procédez comme suit:
la source
encode
retournera un bytestring, alors gardez cela à l'esprit. De plus, cette méthode ne supprime pas les caractères tels que la nouvelle ligne.Potentiellement pour une question différente, mais je fournis ma version de la réponse de @ Alvero (en utilisant unidecode). Je veux faire une bande "régulière" sur mes chaînes, c'est-à-dire le début et la fin de ma chaîne pour les caractères d'espacement, puis remplacer uniquement les autres caractères d'espacement par un espace "régulier", c'est-à-dire
à
,
Nous remplaçons d'abord tous les espaces non-unicode par un espace régulier (et le rejoignons à nouveau),
Et puis nous avons divisé à nouveau, avec la division normale de python, et dépouiller chaque "bit",
Enfin, rejoignez-les à nouveau, mais uniquement si la chaîne réussit un
if
test,Et avec cela,
safely_stripped('ㅤㅤㅤㅤCeñíaㅤmañanaㅤㅤㅤㅤ')
revient correctement'Ceñía mañana'
.la source