[Python3] Basculer entre Shift_JIS, UTF-8 et ASCII

introduction

Dans Python3, affichons d'une manière ou d'une autre la chaîne de caractères de sortie déformée comme '\ udc82Ђ \ udce7 \ udc83J \ udc83 ^ \ udc8a \ udcbf \ udc8e \ udc9a'`` `. C'est une tentative.

référence

Lorsque la chaîne d'octets Shift_JIS est décodée en UTF-8

Par défaut UnicodeDecodeError

Tenter de décoder une chaîne d'octets Shift_JIS (UTF-8 par défaut) entraîne une erreur UnicodeDecodeError

>>> bytes_sjis = "Hirakata Kanji".encode("shift_jis")
>>> bytes_sjis
b'\x82\xd0\x82\xe7\x83J\x83^\x8a\xbf\x8e\x9a'
>>> bytes_sjis.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 0: invalid start byte

Résultat du décodage lorsqu'un gestionnaire d'erreurs est spécifié

L'erreur se produit dans la section précédente car l'argument optionnel errors de `decode ()` est par défaut strict "``. Si vous donnez une autre valeur àʻerrors, aucune erreur ne se produira et une autre chaîne sera renvoyée. L'argument> errors spécifie ce qu'il faut faire si la chaîne d'entrée ne peut pas être convertie selon les règles de codage. Les valeurs qui peuvent être utilisées pour cet argument sont 'strict'(Envoyer une erreur de code unicode)、'replace' (replacement characterEstu+fffdutilisation)、 'ignore'(Supprimez simplement les caractères de l'unicode résultant) 、'backslashreplace' (Séquence d'échappement\xnn```Insérer)est. Unicode HOWTO

En plus de cela, vous pouvez également spécifier '' surrogateescape'`,

'Surrogateescape' '`` - Remplacez la chaîne d'octets par des codes de substitution individuels dans la plage U + DC80 à U + DCFF. 7.2. Codecs - registre de codecs et classe de base

Voyons le résultat de la sortie.

>>> bytes_sjis.decode("utf-8", errors="replace")
'�Ђ�J�^����'
>>> bytes_sjis.decode("utf-8", errors="ignore")
'ЂJ^'
>>> bytes_sjis.decode("utf-8", errors="backslashreplace")
'\\x82Ђ\\xe7\\x83J\\x83^\\x8a\\xbf\\x8e\\x9a'
>>> bytes_sjis.decode("utf-8", errors="surrogateescape")
'\udc82Ђ\udce7\udc83J\udc83^\udc8a\udcbf\udc8e\udc9a'

À propos, l'affichage dans l'environnement Windows (CP932 ~ Shift_JIS), qui n'est pas dans l'environnement UTF-8, est le suivant.

>>> bytes_sjis.decode("utf-8", errors="replace")
'\ufffd\u0402\ufffdJ\ufffd^\ufffd\ufffd\ufffd\ufffd'
>>> bytes_sjis.decode("utf-8", errors="ignore")
'\u0402J^'
>>> bytes_sjis.decode("utf-8", errors="backslashreplace")
'\\x82\u0402\\xe7\\x83J\\x83^\\x8a\\xbf\\x8e\\x9a'
>>> bytes_sjis.decode("utf-8", errors="surrogateescape")
'\udc82\u0402\udce7\udc83J\udc83^\udc8a\udcbf\udc8e\udc9a'

Restaurez la chaîne de caractères d'origine à partir du résultat du décodage de la chaîne d'octets Shift_JIS avec UTF-8.

'replace'Ou'ignore'Lorsque est spécifié, les informations ont été supprimées et ne peuvent pas être restaurées, mais Dans d'autres cas, vous pouvez restaurer la chaîne d'origine comme indiqué ci-dessous. Pourquoi est-ce possible dans le cas de #backslashreplace ...? ?? ??

>>> bytes_sjis = "Hirakata Kanji".encode("shift_jis")
>>> backslash_str = bytes_sjis.decode("utf-8", errors="backslashreplace")
>>> backslash_str.encode().decode("unicode_escape").encode("raw_unicode_escape").decode("shift_jis")
'Hirakata Kanji'

>>> surrogate_str = bytes_sjis.decode("utf-8", errors="surrogateescape")
>>> surrogate_str.encode("utf-8", errors="surrogateescape").decode("shift_jis")
'Hirakata Kanji'

Lorsqu'une chaîne d'octets UTF-8 est décodée en ASCII

Faisons la conversion UTF-8-> ASCII-> UTF-8 ainsi que Shift_JIS-> UTF-8-> Shift_JIS.

Par défaut UnicodeDecodeError

>>> bytes_utf8 = "Hirakata Kanji".encode("utf-8")
>>> bytes_utf8
b'\xe3\x81\xb2\xe3\x82\x89\xe3\x82\xab\xe3\x82\xbf\xe6\xbc\xa2\xe5\xad\x97'
>>> bytes_utf8.decode("ascii")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 0: ordinal not in range(128)

Résultat du décodage lorsqu'un gestionnaire d'erreurs est spécifié

>>> bytes_utf8.decode("ascii", errors="ignore")
''
>>> bytes_utf8.decode("ascii", errors="replace")
'������������������'
>>> bytes_utf8.decode("ascii", errors="backslashreplace")
'\\xe3\\x81\\xb2\\xe3\\x82\\x89\\xe3\\x82\\xab\\xe3\\x82\\xbf\\xe6\\xbc\\xa2\\xe5\\xad\\x97'
>>> bytes_utf8.decode("ascii", errors="surrogateescape")
'\udce3\udc81\udcb2\udce3\udc82\udc89\udce3\udc82\udcab\udce3\udc82\udcbf\udce6\udcbc\udca2\udce5\udcad\udc97'

Restaure la chaîne de caractères d'origine à partir du résultat du décodage de la chaîne d'octets UTF-8 avec ASCII

Pour UTF-8 et ASCII, il semble correct de faire `` .encode (). Decode () ''.

>>> backslash_str = bytes_utf8.decode("utf-8", errors="backslashreplace")
>>> backslash_str.encode().decode()
'Hirakata Kanji'
>>> surrogate_str = bytes_utf8.decode("utf-8", errors="surrogateescape")
>>> surrogate_str.encode().decode()
'Hirakata Kanji'

Exemples courants

Enfin, organisons un exemple de tentative de restauration forcée lorsque vous oubliez de le définir et que les caractères sont brouillés.

Lorsque vous oubliez de définir `` `json outputensure_ascii = False```

>>> import json
>>> ascii_json = json.dumps({"Clé":"valeur"})
>>> ascii_json
'{"\\u30ad\\u30fc": "\\u5024"}'
>>> ascii_json.encode().decode("unicode_escape")
'{"Clé": "valeur"}'
>>> ascii_json.encode().decode("raw_unicode_escape")
'{"Clé": "valeur"}'

Lorsque encoding du résultat obtenu par `requests `n'est pas changé

>>> import requests
>>> r = requests.get('http://www.mof.go.jp/')
>>> r.text
'...
<meta property="og:title" content="\x8dà\x96±\x8fÈ\x83z\x81[\x83\x80\x83y\x81[\x83W" />
...'
>>> r.text.encode("raw_unicode_escape").decode("shift_jis")
'...
<meta property="og:title" content="Page d'accueil du ministère des Finances" />
...'

Recommended Posts

[Python3] Basculer entre Shift_JIS, UTF-8 et ASCII
[Python] Convertir Shift_JIS en UTF-8
Différence entre Ruby et Python Split
Différence entre java et python (mémo)
Différence entre == et est en python
Coopération entre le module python et l'API
Différence entre Python, stftime et strptime
Différence entre la série python2 et la série python3 dict.keys ()
[Python] Différence entre fonction et méthode
Python - Différence entre exec et eval
[Python] Différence entre randrange () et randint ()
[Python] Différence entre trié et trié (Colaboratoire)
Différence d'authenticité entre Python et JavaScript
différence entre les instructions (instructions) et les expressions (expressions) en Python
Différences entre la syntaxe Python et Java
Différences dans la relation entre PHP et Python enfin et quitter
Différence entre @classmethod et @staticmethod en Python
Différence entre append et + = dans la liste Python
Différence entre non local et global en Python
[Python] Différence entre la méthode de classe et la méthode statique
[Python Iroha] Différence entre List et Tuple
[python] Différence entre la sortie rand et randn
Différences de multithreading entre Python et Jython
Différence entre Ruby et Python (syntaxe de base)
Correspondance entre les fonctions intégrées de Python et Rust
Communication de données chiffrées entre Python et C #
[Python] Résumé de la conversion entre les chaînes de caractères et les valeurs numériques (code ascii)
Résumé des différences entre PHP et Python
La réponse de "1/2" est différente entre python2 et 3
[python] Différence entre variable et self. Variable dans la classe
Changer de version de Python
[Python] Mémo de conversion entre les données temporelles et les données numériques
À propos de la différence entre "==" et "is" en python
Comment basculer entre les shells Linux et Mac
Différence approximative entre Unicode et UTF-8 (et ses compagnons)
Expérience de comparaison de la vitesse d'écriture de fichier entre python 2.7.9 et pypy 2.5.0
[Ruby vs Python] Comparaison de référence entre Rails et Flask
Contrôler d'autres programmes depuis Python (communication entre Python ⇔ exe)
Différence entre Ruby et Python en termes de variables
Le comportement de retrait de json.dumps est différent entre python2 et python3
[Ubuntu] [Python] Comparaison de la détection de visage entre dlib et OpenCV
Communication inter-processus entre Ruby et Python (file d'attente de messages POSIX)
Comparez la "relation log et infini" avec Gauche (0.9.4) et Python (3.5.1)
[python] Compresser et décompresser
Astuces Python et Numpy
[Python] pip et roue
Itérateur et générateur Python
Paquets et modules Python
Intégration Vue-Cli et Python
Entre paramétrique et non paramétrique
Ruby, Python et carte
entrée et sortie python
Python et Ruby se séparent
Python asyncio et ContextVar
Module Python num2words Différence de comportement entre l'anglais et le russe
Python> Différence entre la sortie inpbt et print (inpbt)> [1. 2. 3.] / array ([1., 2., 3.], dtype = float32)
Méthode de concaténation de liste en python, différence entre list.extend () et opérateur «+»
Pour aller et venir entre python standard, numpy, pandas ①
Installez pyenv sur MacBookAir et basculez Python à utiliser