IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Unicode, chaîne de caractères et fichier enregistré


Sujet :

Python

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut Unicode, chaîne de caractères et fichier enregistré
    Bonsoir,

    J'ai remarqué que vous aviez réponse à tout, donc je vais en profiter pour vous exposer mon petit souci
    Je voudrais pouvoir désaccentuer proprement des textes de plusieurs milliers de caractères pour un comptage...
    Ca, je l'ai en réalité déjà réussi tant que je fonctionne sous l'IDLE de Python 2.6.2.
    Mais dès que j'essaie de "compiler" avec py2exe pour faire fonctionner mon truc en console : il y a certains caractères "spéciaux qui passent à travers, ce qui fausse le comptage et les fréquences...
    Donc, je me suis mis en chasse et j'ai trouvé ça qui fonctionne très bien aussi en console :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
     
    import unicodedata
     
    ligne = u"Cet appareil, pourtant inférieur à celui de Wadsworth, éveilla un vif \ 
    intérêt dans le petit monde des spécialistes. La couronne extérieure est \ 
    divisée en 27 secteurs : les 26 lettres de l'alphabet clair (ordonné) et une \
    case servant de séparation de mots. Le disque intérieur porte un alphabet \
    désordonné de 26 lettres."
     
    ligne =unicodedata.normalize('NFKD', ligne).encode('ascii','ignore')
    print ligne
    Alors direz-vous ?
    Alors, je voudrais pouvoir traiter différents textes enregistrés sur mon disque dur.
    Mais là, ça plante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
     
    import unicodedata
     
    fichier=open(rep+'\\Echantillon'+str(i)+'.txt','r')  
     
    for line in fichier:
        line='u'+line.strip('\n','')        
        line=unicodedata.normalize('NFKD', line).encode('ascii','ignore')
     
    Traceback (most recent call last):
      File "C:\VRAC_C\frequence_grammes4.py", line 69, in <module>
        line=unicodedata.normalize('NFKD', 'u'+line).encode('ascii','ignore')
    TypeError: normalize() argument 2 must be unicode, not str
    Je comprends pourquoi, mais je n'arrive pas à faire l'équivalent de ;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ligne = u"Cet appareil, pourtant inférieur ..."
    avec un nom de chaîne à la place du texte...

    Si l'un de vous avait l'extrême bonté de prendre 2 min pour me souffler une solution, ce serait vraiment sympa...

    Merci d'avance

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Par défaut
    file.read retourne une chaîne (str). Si le fichier contient des caractères accentués, ils vont apparaître comme deux caractères car ils sont codés. Pour obtenir la chaîne unicode, il faut donc décoder, et pour cela il faut connaître le codage de la chaîne - souvent utf-8, mais ça dépend de l'éditeur.

    Par exemple u"à" (équivalent à u"\xe0" en unicode) se code en utf-8 '\xc3\xa0'.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    >>> print "\xc3\xa0".encode('UTF-8')
    à
    J'espère que ça répond à la question?

  3. #3
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 080
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ligne =unicodedata.normalize('NFKD', unicode(ligne,'utf-8').encode('ascii','ignore')

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut
    Bonjour,

    Comme toujours, quelle réactivité ! Merci.
    @josmiley.
    Il manque une parenthèse après utf-8)
    Cela dit ça marche ensuite, si j'écris :
    [code]#!/usr/bin/env python
    # -*- coding: utf-8 -*-

    import unicodedata
    ligne = u"Cet appareil, pourtant inférieur à celui de Wadsworth, éveilla un vif intérêt dans le petit monde des spécialistes.La couronne extérieure est divisée en 27 secteurs : les 26 lettres de l'alphabet clair (ordonné) et une case servant de séparation de mots. Le disque intérieur porte un alphabet désordonné de 26 lettres."
    Ca a l'air de marcher aussi, à condition que mes fichiers soient enregistrés au format .txt via le bloc-notes mais en utf-8...
    Donc, a priori, c'est bon. Je vais poursuivre mes investigations et vje reviendrai marquer Résolu si c'est bien le cas...

    @Fructidor.
    Non, désolé je n'ai pas été très clair...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ligne = u"Cet appareil, pourtant inférieur à celui de Wadsworth,...
    ici "j'applique" le u directement au contenant u"blabla..."
    Moi je voulais appliquer le u au "conteneur", mais je ne peux pas faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ligne = "Cet appareil, pourtant inférieur à celui de Wadsworth,..."
    print uligne
    Ceci dit ton message m'a permis de comprendre ce que j'avais lu quelque part à propos d caractères spéciaux (3) à écrire en début de ligne : je n'avais pas compris d'où ils sortaient ; là avec mes fichiers enregistrés en UTF-8, je les ai vu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "\xef\xbb\xbfCet appareil,...
    ou encore :
    Apparemment, la méthode de josmiley fonctionne : il doit avoir une grande aptitude à débrouiller ce qui est confus.

    Merci encore

    @+

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut
    Re,

    Arf, un doute subit m'a étreint : après vérification ça se confirme !
    Mais c'est inhérent à la méthode et pas à vos réponses :
    le 'ignore' fait que la ligne de transforlation, très normalement, me shunte le "œ"...

    Il ne peut évidemment pas me le remplacer par oe, tout comme son compère ne peut pas être remplacé par ae...

    Y a-t-il un moyen autre que de parcourir visuellement tous les fichiers à la recherche de ces deux exceptions ?

    @+

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut Hmmm
    De toutes façon, il faut savoir comment est encodé le fichier.
    Mais pourquoi ne pas faire faire les conversions 'plus bas' en utilisant 'codecs'?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from codecs import open
    fichier = open('fichier.txt', encoding='utf8')
    for ligne in fichier:
        #...
    -W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut
    Salut,

    Tiens, c'est donc possible un truc comme ça ?!!...
    Merci, donc...

    Mes fichiers sont tous repassés par le Bloc-notes, où je les ai enregistrés avec l'extension .txt et le codage utf-8.
    Mes fichiers stockés sur le disque dur sont donc (en principe) en utf-8...
    Le système proposé par josmiley marche très bien aussi.
    Mais il me semble que tant ta méthode que la sienne ne me permette pas de remplacer les deux ligatures connues par ae (rare quand même) et oe (bien plus fréquent chez les les Editeurs de bouquins).

    C'est le seul point qui fait tache : si je veux pouvoir donner mon script, après passage par py2exe pour le "compiler", à qui n'a pas Python (et ne souhaite pas l'installer), la méthode que j'avais élaborée pour le fonctionnement avec l'IDLE de Windows (à partir d'un dictionnaire), doit se comporter en .exe de la même façon qu'en .py...
    Or, ce n'est pas le cas : les lettres accentuées ne sont remplacées...

    Avec les méthodes proposées, si, à part les ligatures...
    Une idée pour remplacer la ligature par deux lettres ?

    @+

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut utf-8 -> unicode
    Bonsoir,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> x = u'œuf, cœur, bœuf'
    >>> x
    u'\x9cuf, c\x9cur, b\x9cuf'
    >>> y = x.encode('utf-8')
    >>> y
    '\xc2\x9cuf, c\xc2\x9cur, b\xc2\x9cuf'
    >>> z = y.decode('utf-8')
    >>> z
    u'\x9cuf, c\x9cur, b\x9cuf'
    => Comment est codé œ dans le fichier supposé UTF-8?

    -W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut
    Salut,

    Merci de t'intéresser ainsi à cette difficulté...
    Voilà un extrait du fichier incriminé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    .... jusqu\x92en plein c\x9cur de l\x92Allemagne nazie en guerre.
    Apparemment il est bien codé en UTF-8.

    @+

  10. #10
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Citation Envoyé par yoshik Voir le message
    Salut,

    Merci de t'intéresser ainsi à cette difficulté...
    Voilà un extrait du fichier incriminé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    .... jusqu\x92en plein c\x9cur de l\x92Allemagne nazie en guerre.
    Apparemment il est bien codé en UTF-8.

    @+
    UTF-8 code en ASCII ce qui est < 127 et (en gros) multibyte au delà.

    Les apostrophes de "jusqu'en" ou de l'Allemagne sont des caractères ASCII.
    On devrait les voir tels que i.e. ' et non \x92 (qui est > 128)

    C'est autre chose, probablement du CP1252, le défaut Windows (que j'utilise aussi)
    Galère hein?

    -W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut
    Re,

    Bon, par flemme, j'avais ouvert le fichier avec le bloc notes et fait un copier/coller dans une chaîne python...
    Je te prie de m'en excuser pour la perte de temps que j'ai occasionnée.

    Cette fois, j'ai utilisé le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> for i in range(3):
    	line=f.readline()
    	line
    Et j'ai pour la première ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "\xef\xbb\xbfLa Seconde Guerre mondiale ou la Deuxi\xc3\xa8me Guerre mondiale[1] est un conflit arm\xc3\xa9 \xc3\xa0 l'\xc3\xa9chelle plan\xc3\xa9taire...
    Et le morceau de ligne citée dans le post précédent est cette fois :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ....jusqu\xe2\x80\x99en plein c\xc5\x93ur de l\xe2\x80\x99Allemagne nazie en guerre.
    La présence au début des 3 caractères spéciaux \xef\xbb\xbf, puis pour le é des 2 codes \xc3\xa9 prouve bien que c'est de l'UTF-8, non ?

    @+

    Euh, je pige pas tout :
    * d'un côté l'apostrophe est là es qualité : l'\xc3\xa9chelle
    * d'un autre côté c'est un truc bizarre : l\xe2\x80\x99Allemagne

    Et pourtant le traitement façon josmiley semble propre :
    Dingue cette histoire,
    va falloir que je vérifie avec ma méthode initiale que je ne perds rien en route...

    Après traitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ....un conflit arme a l'echelle planetaire 
    ..................
    ...jusquen plein cur de lAllemagne nazie en guerre.
    Il y a donc bien des apostrophes qui disparaissent... Elles n'en sont peut-être pas : seule explication plausible, non ?...
    Ce texte a été obtenu via OCR par un ami : je n'ai fait que le ré-enregistrer en utf-8 via le bloc-notes...L'OCR est un maillon de trop : je n'aime pas ça. Il va falloir que je pousse un peu plus les investigations.

    Mais en supposant que tout soit ok, comment remplacer une ligature par deux lettres distinctes par le procédé josmiley ?
    Si je substitue 'replace' à 'ignore', j'obtiens c?ur et pas coeur... normal la ligature existe avec un codage ANSi, mais pas en ASCII...
    Possible d'imposer qqch à 'replace' ?

    Ca me démangeait trop : j'ai vérifié ce soir : il des ' et des ’ ...ça me rassure.

  12. #12
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Mais en supposant que tout soit ok, comment remplacer une ligature par deux lettres distinctes par le procédé josmiley ?
    Si je substitue 'replace' à 'ignore', j'obtiens c?ur et pas coeur... normal la ligature existe avec un codage ANSi, mais pas en ASCII...
    Possible d'imposer qqch à 'replace' ?
    Principes:
    1 - on doit pouvoir transcoder n'importe quoi en UTF-8 sans perte pour peu qu'on sache en quoi est fait "n'importe quoi".
    En cas de doute, passe le fichier à utrac - ca ne fait pas tout mais..-
    => ignore çà va pour passer d'UTF-8 à un encodage ASCII ou autre dans lequel on ne sait pas représenter l'ensemble des codes UTF-8.

    2 - le codage unicode de Python n'est pas de l'UTF-8. C'est une représentation 'interne' utilisable en prenant la peine de faire .decode, .encode des suites d'octets lues dans ce format interne.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Ce texte a été obtenu via OCR par un ami : je n'ai fait que le ré-enregistrer en utf-8 via le bloc-notes...L'OCR est un maillon de trop : je n'aime pas ça. Il va falloir que je pousse un peu plus les investigations.
    pour faire cela, il serait préférable de passer par la suite:
    • utrac : quel est l'encodage du fichier
    • iconv : pour effectuer la conversion.


    -W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut
    Bonsoir,

    Utrac, iconv ? Connais pas, jamais entendu parler...
    Je viens de "googler" : il semblerait qur cela appartienne au monde Linux, non ?
    Merci. Je vais suivre l'affaire...

    @+

Discussions similaires

  1. Réponses: 0
    Dernier message: 15/11/2011, 16h42
  2. Exports de chaînes de caractère dans fichier texte
    Par Stormy31 dans le forum Langage
    Réponses: 4
    Dernier message: 29/01/2009, 14h31
  3. Réponses: 8
    Dernier message: 16/06/2006, 02h06
  4. Rechercher une chaîne de caractère dans une série de fichier
    Par Edoxituz dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 28/02/2006, 13h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo