Détection de l'encodage des entrées utilisateur

Le
Guillaume Lemaître
Bonjour,

Mon problème initial est de pouvoir faire tourner une expression
régulière du genre "w+" sur une entrée utilisateur avec Python 2.4.3
(au minimum)

C'est donc fort logiquement que j'écris (dans mon_test.py) :

import sys, re

print re.match("w+", sys.argv[1]).group(0)

$ ./mon_test.py creation
creation
$

Super, ça a l'air de marcher. Mais avec l'entrée suivante :

$ ./mon_test.py création
cr
$

C'est déjà moins un succès. Du coup, je me documente sur internet, et je
modifie la commande principale par :

print re.match("w+",
sys.argv[1].decode("utf-8"),
re.UNICODE).group(0)

$ ./mon_test.py création
création
$

Super, ça marche à nouveau. Comme je suis hyper joueur, je modifie
l'encodage de mon terminal Gnome, et je le passe en iso8859-15.

$ ./mon_test.py création
Traceback (most recent call last):
File "./mon_test.py", line 5, in <module>
print re.match("w+", sys.argv[1].decode("utf-8"), re.UNICODE).group(0)
File "/usr/lib64/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe9 in position 2:
invalid continuation byte
$

Ce n'est pas tant que je ne m'y attendais pas. J'essaie de décoder une
donnée supposée être de l'utf-8 alors que c'est de l'iso8859-15.

Ma question est très simple : comment détecter l'encodage de l'entrée ?
Toutes les aides que j'ai vu sur l'Internet par de sys.stdin.encoding ou
de différentes méthodes du module locale. Dans tous les cas, je récupère
soit "ascii", soit "utf-8" comme encodage, et ce n'est pas ce que je
fournis.

D'avance merci pour vos éclaircissements,

Guillaume
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Laurent Claessens
Le #23512961
Ma question est très simple : comment détecter l'encodage de l'entrée ?




Pour autant que je sache, la réponse est aussi simple que la question :
c'est impossible.

Il existe des méthodes heuristiques (que je ne connais pas), mais elles
ne sont pas fiables. Je suppose que ça se base sur le fait qu'en
Français le code non-ascii qui arrive le plus souvent doit être le «é»,
ou ce genre de trucs.

J'espère que quelqu'un va me contredire ;)

bonne journée
Laurent
Alain Ketterlin
Le #23513101
Laurent Claessens
Ma question est très simple : comment détecter l'encodage de l 'entrée ?



Pour autant que je sache, la réponse est aussi simple que la question
: c'est impossible.



Effectivement.

Il existe des méthodes heuristiques (que je ne connais pas), mais
elles ne sont pas fiables. Je suppose que ça se base sur le fait qu' en
Français le code non-ascii qui arrive le plus souvent doit être le
«é», ou ce genre de trucs.



Hmmm, ça peut éventuellement bien se passer si on sait au prà ©alable que
l'on a soit du iso-8859-1 soit de l'utf-8, mais ça ne donne rien de
probant avec UCS-32 etc.

La méthode "prescrite" (au moins dans POSIX) consiste à utiliser la
locale. Voir le package locale, et en particulier la documentation de
locale.getdefaultlocale() pour une méthode un peu plus solide.

J'espère que quelqu'un va me contredire ;)



Malheureusement...

-- Alain.
Guillaume Lemaître
Le #23513191
Le 29/06/2011 11:46, Laurent Claessens a écrit :

Ma question est très simple : comment détecter l'encodage de l'entrée ?




Pour autant que je sache, la réponse est aussi simple que la question :
c'est impossible.

Il existe des méthodes heuristiques (que je ne connais pas), mais elles
ne sont pas fiables. Je suppose que ça se base sur le fait qu'en
Français le code non-ascii qui arrive le plus souvent doit être le «é»,
ou ce genre de trucs.

J'espère que quelqu'un va me contredire ;)

bonne journée
Laurent



Sac-à-papier, c'est bien ce que je craignais.

Merci tout de même,

Guillaume
Web Dreamer
Le #23544081
Guillaume Lemaître a écrit ce mardi 28 juin 2011 20:14 dans

Ce n'est pas tant que je ne m'y attendais pas. J'essaie de décoder une
donnée supposée être de l'utf-8 alors que c'est de l'iso8859-15.

Ma question est très simple : comment détecter l'encodage de l'entrée ?
Toutes les aides que j'ai vu sur l'Internet par de sys.stdin.encoding ou
de différentes méthodes du module locale. Dans tous les cas, je récupère
soit "ascii", soit "utf-8" comme encodage, et ce n'est pas ce que je
fournis.



Très simplement avec le module chardet
http://pypi.python.org/pypi/chardet/
http://chardet.feedparser.org/
(easy_install chardet devrait l'installer)

Sur une machine:
import chardet
chardet.detect( 'création' )






{'confidence': 0.505, 'encoding': 'utf-8'}

Sur une "autre" machine:
import chardet
chardet.detect( 'création' )






{'confidence': 0.60317487125232372, 'encoding': 'ISO-8859-2'}

Donc tu peux utiliser:
encoding = chardet.detect(my_string)['encoding']

Et le tour est joué.

--
Web Dreamer
News123
Le #23812951
Est-ce-que tu as un peut plus de context???


Ton text a analyser vient d'ou?


- HTML / XML devrai avoir les entetes qui decrivent l'encodage.
- email: peut-etre dans les entetes, mais je ne sais pas.
- console: locales / le variales d'env
- fichier inconnues sur ta disque: faut prendre les algo's heuristiques

On 06/28/2011 08:14 PM, Guillaume Lemaître wrote:
Bonjour,

Mon problème initial est de pouvoir faire tourner une expression
régulière du genre "w+" sur une entrée utilisateur avec Python 2.4.3
(au minimum)

C'est donc fort logiquement que j'écris (dans mon_test.py) :

import sys, re

print re.match("w+", sys.argv[1]).group(0)

$ ./mon_test.py creation
creation
$

Super, ça a l'air de marcher. Mais avec l'entrée suivante :

$ ./mon_test.py création
cr
$

C'est déjà moins un succès. Du coup, je me documente sur internet, et je
modifie la commande principale par :

print re.match("w+",
sys.argv[1].decode("utf-8"),
re.UNICODE).group(0)

$ ./mon_test.py création
création
$

Super, ça marche à nouveau. Comme je suis hyper joueur, je modifie
l'encodage de mon terminal Gnome, et je le passe en iso8859-15.

$ ./mon_test.py création
Traceback (most recent call last):
File "./mon_test.py", line 5, in <module>
print re.match("w+", sys.argv[1].decode("utf-8"), re.UNICODE).group(0)
File "/usr/lib64/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe9 in position 2:
invalid continuation byte
$

Ce n'est pas tant que je ne m'y attendais pas. J'essaie de décoder une
donnée supposée être de l'utf-8 alors que c'est de l'iso8859-15.

Ma question est très simple : comment détecter l'encodage de l'entrée ?
Toutes les aides que j'ai vu sur l'Internet par de sys.stdin.encoding ou
de différentes méthodes du module locale. Dans tous les cas, je récupère
soit "ascii", soit "utf-8" comme encodage, et ce n'est pas ce que je
fournis.

D'avance merci pour vos éclaircissements,

Guillaume
Publicité
Poster une réponse
Anonyme