J'ai une chaîne Unicode en Python, et je voudrais supprimer tous les accents (diacritiques).
J'ai trouvé sur le Web une manière élégante de le faire en Java:
- convertir la chaîne Unicode dans sa longue forme normalisée (avec un caractère séparé pour les lettres et les signes diacritiques)
- supprimez tous les caractères dont le type Unicode est "diacritique".
Dois-je installer une bibliothèque telle que pyICU ou est-ce possible avec seulement la bibliothèque standard python? Et qu'en est-il de python 3?
Remarque importante: je voudrais éviter le code avec un mappage explicite des caractères accentués à leur homologue non accentué.
python
python-3.x
unicode
python-2.x
diacritics
MiniQuark
la source
la source
unidecode
remplace°
pardeg
. Il fait plus que simplement supprimer les accents.Que dis-tu de ça:
Cela fonctionne aussi sur les lettres grecques:
La catégorie de caractères "Mn" signifie
Nonspacing_Mark
, qui est similaire à unicodedata.combining dans la réponse de MiniQuark (je n'ai pas pensé à unicodedata.combining, mais c'est probablement la meilleure solution, car elle est plus explicite).Et gardez à l'esprit que ces manipulations peuvent modifier considérablement la signification du texte. Les accents, trémas, etc. ne sont pas de la "décoration".
la source
unicodedata.name
, soit décomposer et utiliser une table similaire - dont vous auriez besoin pour les lettres grecques de toute façon (Α est juste "LETTRE MAJUSCULE GRECQUE ALPHA").A
. Si vous ne le voulez pas, ne le faites pas, mais dans les deux cas, vous remplacez un sosie latin (proche).ß
en asciiss
par exemple. J'utiliserais toujoursunidecode
pour éviter les accidents.Je viens de trouver cette réponse sur le Web:
Cela fonctionne bien (pour le français, par exemple), mais je pense que la deuxième étape (supprimer les accents) pourrait être mieux gérée que de supprimer les caractères non ASCII, car cela échouera pour certaines langues (grec, par exemple). La meilleure solution serait probablement de supprimer explicitement les caractères unicode qui sont étiquetés comme étant des signes diacritiques.
Edit : cela fait l'affaire:
unicodedata.combining(c)
retournera vrai si le caractèrec
peut être combiné avec le caractère précédent, c'est principalement s'il s'agit d'un diacritique.Edit 2 :
remove_accents
attend une chaîne unicode , pas une chaîne d'octets. Si vous avez une chaîne d'octets, vous devez la décoder en une chaîne unicode comme celle-ci:la source
nkfd_form = unicodedata.normalize('NFKD', unicode(input_str, 'utf8'))
, 'utf8'
est un "filet de sécurité" nécessaire si vous testez l'entrée dans le terminal (qui par défaut n'utilise pas unicode). Mais généralement , vous ne devez l'ajouter, car si vous supprimez des accents alorsinput_str
est très susceptible d'être déjà UTF8. Mais ça ne fait pas de mal d'être en sécurité.remove_accents
place d'une chaîne régulière (u "é" au lieu de "é"). Vous avez transmis une chaîne régulière àremove_accents
, donc lorsque vous essayez de convertir votre chaîne en chaîne unicode, leascii
codage par défaut a été utilisé. Ce codage ne prend en charge aucun octet dont la valeur est> 127. Lorsque vous avez tapé "é" dans votre shell, votre système d'exploitation l'a encodé, probablement avec UTF-8 ou un encodage de page de codes Windows, et cela comprenait des octets> 127. Je vais changer ma fonction afin de supprimer la conversion en unicode: elle bombardera plus clairement si une chaîne non unicode est passée.En fait, je travaille sur des projets compatibles python 2.6, 2.7 et 3.4 et je dois créer des identifiants à partir d'entrées utilisateur gratuites.
Grâce à vous, j'ai créé cette fonction qui fait des merveilles.
résultat:
la source
text = unicode(text, 'utf-8')
. Une solution de contournement pour cela était d'ajouterexcept TypeError: pass
Cela gère non seulement les accents, mais aussi les "traits" (comme en ø etc.):
C'est la façon la plus élégante à laquelle je peux penser (et cela a été mentionné par alexis dans un commentaire sur cette page), bien que je ne pense pas que ce soit vraiment très élégant. En fait, c'est plus un hack, comme souligné dans les commentaires, car les noms Unicode sont - vraiment des noms, ils ne garantissent pas la cohérence ou quoi que ce soit.
Il y a encore des lettres spéciales qui ne sont pas gérées par cela, comme les lettres tournées et inversées, car leur nom unicode ne contient pas 'AVEC'. Cela dépend de ce que vous voulez faire de toute façon. J'avais parfois besoin d'un dépouillement d'accent pour obtenir l'ordre de tri du dictionnaire.
NOTE ÉDITÉE:
Intégration des suggestions des commentaires (gestion des erreurs de recherche, code Python-3).
la source
unicode
appel de fonction avec python 3? Je pense qu'un regex plus serré à la place dufind
éviterait tous les problèmes mentionnés dans le commentaire ci-dessus, et aussi, la mémorisation aiderait les performances quand c'est un chemin de code critique.unicode
transtypage n'est plus approprié dans Python 3. Dans tous les cas, d'après mon expérience, il n'y a pas de solution universelle et élégante à ce problème. Selon l'application, toute approche a ses avantages et ses inconvénients. Des outils de qualité commeunidecode
sont basés sur des tables fabriquées à la main. Certaines ressources (tables, algorithmes) sont fournies par Unicode, par exemple. pour le classement.En réponse à la réponse de @ MiniQuark:
J'essayais de lire dans un fichier csv qui était à moitié français (contenant des accents) et aussi quelques chaînes qui finiraient par devenir des entiers et des flottants. À titre de test, j'ai créé un
test.txt
fichier qui ressemblait à ceci:J'ai dû inclure des lignes
2
et3
le faire fonctionner (que j'ai trouvé dans un ticket python), ainsi qu'incorporer le commentaire de @ Jabba:Le résultat:
(Remarque: je suis sous Mac OS X 10.8.4 et j'utilise Python 2.7.3)
la source
remove_accents
était destiné à supprimer les accents d'une chaîne unicode. Si une chaîne d'octets lui est transmise, il essaie de la convertir en une chaîne unicode avecunicode(input_str)
. Cela utilise l'encodage par défaut de python, qui est "ascii". Étant donné que votre fichier est codé en UTF-8, cela échouerait. Les lignes 2 et 3 changent l'encodage par défaut de python en UTF-8, alors cela fonctionne, comme vous l'avez découvert. Une autre option est de passerremove_accents
une chaîne unicode: supprimez les lignes 2 et 3, et sur la dernière ligne remplacezelement
parelement.decode("utf-8")
. J'ai testé: ça marche. Je mettrai à jour ma réponse pour clarifier les choses.iso-8859-1
, ce que je ne peux malheureusement pas utiliser avec cette fonction!)reload(sys); sys.setdefaultencoding("utf-8")
est un hack douteux parfois recommandé pour les systèmes Windows; voir stackoverflow.com/questions/28657010/… pour plus de détails.gensim.utils.deaccent (texte) de Gensim - modélisation de sujets pour les humains :
Une autre solution est unidecode .
Notez que la solution suggérée avec unicodedata ne supprime généralement les accents que dans certains caractères (par exemple, elle se transforme
'ł'
en''
, plutôt qu'en'l'
).la source
deaccent
donne toujoursł
au lieu del
.NumPy
etSciPy
de supprimer les accents.Certaines langues combinent les signes diacritiques comme lettres de langue et les signes diacritiques accentués pour spécifier l'accent.
Je pense qu'il est plus sûr de spécifier explicitement les diactriques que vous souhaitez supprimer:
la source