Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

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

5 réponses
Avatar
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

5 réponses

Avatar
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.

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
Avatar
Alain Ketterlin
Laurent Claessens writes:

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.
Avatar
Guillaume Lemaître
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
Avatar
Web Dreamer
Guillaume Lemaître a écrit ce mardi 28 juin 2011 20:14 dans
<4e0a1a08$0$29534$ :

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
Avatar
News123
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