web-dev-qa-db-fra.com

Lecture de caractère à partir du fichier dans Python

Dans un fichier texte, il y a une chaîne "je n'aime pas ça".

Cependant, lorsque je le lis dans une chaîne, il devient "Je ne\xe2\x80\x98t pas comme ça". Je comprends que\u2018 est la représentation unicode de "'". j'utilise

f1 = open (file1, "r")
text = f1.read()

commande pour faire la lecture.

Maintenant, est-il possible de lire la chaîne de telle manière que, lorsqu'elle est lue dans la chaîne, il se trouve "je n'aime pas ceci", au lieu de "je ne\xe2\x80\x98t comme ceci"?

Deuxième édition: j'ai vu certaines personnes utiliser la cartographie pour résoudre ce problème, mais en réalité, n'y a-t-il pas de conversion intégrée qui effectue ce type de conversion ANSI en unicode (et vice versa)?

92
Graviton

Réf.: http://docs.python.org/howto/unicode

La lecture d'Unicode à partir d'un fichier est donc simple:

import codecs
f = codecs.open('unicode.rst', encoding='utf-8')
for line in f:
    print repr(line)

Il est également possible d'ouvrir des fichiers en mode de mise à jour, permettant à la fois la lecture et l'écriture:

f = codecs.open('test', encoding='utf-8', mode='w+')
f.write(u'\u4500 blah blah blah\n')
f.seek(0)
print repr(f.readline()[:1])
f.close()

[~ # ~] edit [~ # ~] : Je suppose que votre objectif est simplement de pouvoir lire le fichier correctement dans un chaîne en Python. Si vous essayez de convertir en chaîne ASCII à partir d'Unicode, il n'existe aucun moyen direct de le faire, car les caractères Unicode n'existent pas nécessairement en ASCII.

Si vous essayez de convertir en chaîne ASCII, essayez l’une des méthodes suivantes:

  1. Remplacez les caractères Unicode spécifiques par ASCII équivalents, si vous ne souhaitez traiter que quelques cas particuliers, tels que cet exemple particulier

  2. Utilisez la méthode normalize() du module unicodedata et la méthode string.encode() pour convertir au mieux le prochain proche ASCII équivalent (Ref - https://web.archive.org/web/20090228203858/http://techxplorer.com/2006/07/18/converting-unicode-to-ascii-using-python ):

    >>> teststr
    u'I don\xe2\x80\x98t like this'
    >>> unicodedata.normalize('NFKD', teststr).encode('ascii', 'ignore')
    'I donat like this'
    
143
Jay

Il y a quelques points à considérer.

Un caractère\u2018 peut apparaître uniquement comme un fragment de représentation d'une chaîne unicode en Python, par ex. si vous écrivez:

>>> text = u'‘'
>>> print repr(text)
u'\u2018'

Maintenant, si vous voulez simplement imprimer joliment la chaîne Unicode, utilisez simplement la méthode encode de Unicode:

>>> text = u'I don\u2018t like this'
>>> print text.encode('utf-8')
I don‘t like this

Pour vous assurer que chaque ligne d'un fichier est lue en tant que Unicode, vous feriez mieux d'utiliser le codecs.open fonction au lieu de open, ce qui vous permet de spécifier le codage du fichier:

>>> import codecs
>>> f1 = codecs.open(file1, "r", "utf-8")
>>> text = f1.read()
>>> print type(text)
<type 'unicode'>
>>> print text.encode('utf-8')
I don‘t like this
15
DzinX

Mais c’est vraiment "je n’aime pas ça" et non "je n’aime pas ça". Le caractère u '\ u2018' est un caractère complètement différent de "'" (et, visuellement, devrait correspondre davantage à "'").

Si vous essayez de convertir unicode codé en ASCII simple, vous pouvez peut-être conserver un mappage de la ponctuation unicode que vous souhaitez traduire en ASCII.

punctuation = {
  u'\u2018': "'",
  u'\u2019': "'",
}
for src, dest in punctuation.iteritems():
  text = text.replace(src, dest)

Il y a énormément de caractères de ponctuation en unicode , cependant, mais je suppose que vous ne pouvez compter que sur quelques-uns d'entre eux réellement utilisés par les applications qui créent les documents que vous lisez.

6
Logan

Laissant de côté le fait que votre fichier texte est cassé (U + 2018 est un guillemet gauche, pas une apostrophe): iconv peut être utilisé pour translittérer des caractères Unicode en ascii.

Vous devrez google pour "iconvcodec", car le module ne semble plus être supporté et je ne trouve pas de page d'accueil canonique pour celui-ci.

>>> import iconvcodec
>>> from locale import setlocale, LC_ALL
>>> setlocale(LC_ALL, '')
>>> u'\u2018'.encode('ascii//translit')
"'"

Vous pouvez également utiliser l'utilitaire de ligne de commande iconv pour nettoyer votre fichier:

$ xxd foo
0000000: e280 980a                                ....
$ iconv -t 'ascii//translit' foo | xxd
0000000: 270a                                     '.
3
user3850

Il est possible que vous ayez en quelque sorte une chaîne non-unicode avec des caractères d'échappement Unicode, par exemple:

>>> print repr(text)
'I don\\u2018t like this'

Cela m'est réellement arrivé une fois auparavant. Vous pouvez utiliser un unicode_escape codec pour décoder la chaîne en unicode, puis l'encoder dans le format de votre choix:

>>> uni = text.decode('unicode_escape')
>>> print type(uni)
<type 'unicode'>
>>> print uni.encode('utf-8')
I don‘t like this
2
DzinX

En réalité, U + 2018 est la représentation Unicode du caractère spécial ‘. Si vous le souhaitez, vous pouvez convertir les occurrences de ce caractère en U + 0027 avec ce code:

text = text.replace (u"\u2018", "'")

De plus, qu'utilisez-vous pour écrire le fichier? f1.read() devrait retourner une chaîne qui ressemble à ceci:

'I don\xe2\x80\x98t like this'

S'il renvoie this chaîne, le fichier est écrit de manière incorrecte:

'I don\u2018t like this'
1
John Millikin

C'est la façon dont Pythons vous montre les chaînes codées en Unicode. Mais je pense que vous devriez pouvoir imprimer la chaîne à l'écran ou l'écrire dans un nouveau fichier sans aucun problème.

>>> test = u"I don\u2018t like this"
>>> test
u'I don\u2018t like this'
>>> print test
I don‘t like this
1
xardias

Il est également possible de lire un fichier texte encodé en utilisant la méthode python 3 read:

f = open (file.txt, 'r', encoding='utf-8')
text = f.read()
f.close()

Avec cette variante, il n’est pas nécessaire d’importer de bibliothèques supplémentaires.

1
Stein