J'utilise un outil tiers qui génère un fichier au format Unicode. Cependant, je préfère que ce soit en ASCII. L'outil n'a pas de paramètres pour changer le format de fichier.
Quel est le meilleur moyen de convertir le format de fichier entier en utilisant Python?
Vous pouvez convertir le fichier assez facilement en utilisant simplement la fonction unicode
, mais vous rencontrerez des problèmes avec les caractères Unicode sans équivalent ASCII direct.
Ce blog recommande le module unicodedata
, qui semble prendre en charge la conversion approximative des caractères sans valeurs correspondantes directes ASCII, par exemple.
>>> title = u"Klüft skräms inför på fédéral électoral große"
est généralement converti en
Klft skrms infr p fdral lectoral groe
ce qui est assez faux. Cependant, en utilisant le module unicodedata
, le résultat peut être beaucoup plus proche du texte d'origine:
>>> import unicodedata
>>> unicodedata.normalize('NFKD', title).encode('ascii','ignore')
'Kluft skrams infor pa federal electoral groe'
_ {Je pense que c'est un problème plus profond que vous ne le réalisez}. Il est facile de changer le fichier de Unicode en ASCII, cependant, traduire tous les caractères Unicode en des équivalents raisonnables ASCII (de nombreuses lettres ne sont pas disponibles dans les deux codages) en est un autre.
Ce tutoriel Python Unicode peut vous donner une meilleure idée de ce qu'il advient des chaînes Unicode traduites en ASCII: http://www.reportlab.com/i18n/python_unicode_tutorial.html
Voici une citation utile du site:
Python 1.6 obtient également une fonction intégrée "unicode", à laquelle vous pouvez spécifier le codage:
> >>> unicode('hello') u'hello'
> >>> unicode('hello', 'ascii') u'hello'
> >>> unicode('hello', 'iso-8859-1') u'hello'
> >>>
Ils renvoient tous les trois la même chose, car les caractères de «Bonjour» sont communs aux trois encodages.
Encodons maintenant quelque chose avec un accent européen, ce qui est en dehors de ASCII. Ce que vous voyez sur une console peut dépendre des paramètres régionaux de votre système d'exploitation. Windows me permet de taper ISO-Latin-1.
> >>> a = unicode('André','latin-1')
> >>> a u'Andr\202'
Si vous ne pouvez pas taper une lettre aiguë e, vous pouvez entrer la chaîne 'Andr\202', qui est sans ambiguïté.
Unicode prend en charge toutes les opérations courantes telles que l'itération et le fractionnement. Nous ne les verrons pas ici.
En passant, c’est une commande linux iconv
pour faire ce genre de travail.
iconv -f utf8 -t ascii <input.txt >output.txt
Pour mon problème où je voulais juste ignorer les caractères non-ascii et sortir uniquement la sortie ascii, la solution ci-dessous a très bien fonctionné:
import unicodedata
input = open(filename).read().decode('UTF-16')
output = unicodedata.normalize('NFKD', input).encode('ASCII', 'ignore')
Comme ça:
uc = open(filename).read().decode('utf8')
ascii = uc.decode('ascii')
Notez cependant que cela échouera avec une exception UnicodeDecodeError
s’il existe des caractères qui ne peuvent pas être convertis en ASCII.
EDIT: Comme Pete Karl vient de le dire, il n’existe pas de correspondance individuelle entre Unicode et ASCII. Ainsi, certains caractères ne peuvent tout simplement pas être convertis de manière à préserver les informations. De plus, la norme ASCII est plus ou moins un sous-ensemble de UTF-8, vous n'avez donc même pas besoin de décoder.
Voici un code simple (et stupide) pour coder la traduction. Je suppose (mais vous ne devriez pas) que le fichier d'entrée est en UTF-16 (Windows appelle cela simplement «Unicode»).
input_codec = 'UTF-16'
output_codec = 'ASCII'
unicode_file = open('filename')
unicode_data = unicode_file.read().decode(input_codec)
ascii_file = open('new filename', 'w')
ascii_file.write(unicode_data.write(unicode_data.encode(output_codec)))
Notez que cela ne fonctionnera pas si le fichier Unicode contient des caractères qui ne sont pas également des caractères ASCII. Vous pouvez effectuer les opérations suivantes pour transformer des caractères non reconnus en '?':
ascii_file.write(unicode_data.write(unicode_data.encode(output_codec, 'replace')))
Consultez la documentation pour des choix plus simples. Si vous avez besoin de faire quelque chose de plus sophistiqué, vous pouvez consulter Le marteau UNICODE sur le livre de recettes Python.
Il est important de noter qu’il n’existe pas de format de fichier «Unicode». Unicode peut être codé en octets de différentes manières. Le plus souvent UTF-8 ou UTF-16. Vous aurez besoin de savoir lequel de votre outil tiers produit en sortie. Une fois que vous savez cela, la conversion entre différents encodages est assez facile:
in_file = open("myfile.txt", "rb")
out_file = open("mynewfile.txt", "wb")
in_byte_string = in_file.read()
unicode_string = bytestring.decode('UTF-16')
out_byte_string = unicode_string.encode('ASCII')
out_file.write(out_byte_string)
out_file.close()
Comme indiqué dans les autres réponses, vous souhaiterez probablement fournir un gestionnaire d'erreurs à la méthode d'encodage. Utiliser 'remplacer' comme gestionnaire d'erreurs est simple, mais modifiera votre texte s'il contient des caractères qui ne peuvent pas être représentés en ASCII.
Comme d'autres afficheurs l'ont noté, ASCII est un sous-ensemble de Unicode.
Cependant si vous:
Ensuite, l'exemple ci-dessous montre comment procéder:
mystring = u'bar'
type(mystring)
<type 'unicode'>
myasciistring = (mystring.encode('ASCII'))
type(myasciistring)
<type 'str'>