web-dev-qa-db-fra.com

Conversion d'une chaîne d'octets en chaîne unicode

J'ai un code tel que:

a = "\u0432"
b = u"\u0432"
c = b"\u0432"
d = c.decode('utf8')

print(type(a), a)
print(type(b), b)
print(type(c), c)
print(type(d), d)

Et sortie:

<class 'str'> в
<class 'str'> в
<class 'bytes'> b'\\u0432'
<class 'str'> \u0432

Pourquoi dans ce dernier cas, je vois un code de caractère, au lieu du caractère? Comment puis-je transformer la chaîne Byte en chaîne Unicode qu'en cas de sortie, j'ai vu le caractère, au lieu de son code?

28
Alex T

Dans les chaînes (ou les objets Unicode dans Python 2), \u a une signification particulière, à savoir: "voici un caractère Unicode spécifié par son ID Unicode". Par conséquent u"\u0432" donnera le caractère в.

Le b'' le préfixe vous indique qu'il s'agit d'une séquence d'octets 8 bits, et que l'objet octets n'a pas de caractères Unicode, donc le \u le code n'a pas de signification particulière. Par conséquent, b"\u0432" n'est que la séquence des octets \, u, 0, 4, 3 et 2.

Vous disposez essentiellement d'une chaîne de 8 bits contenant non pas un caractère Unicode, mais la spécification d'un caractère Unicode.

Vous pouvez convertir cette spécification à l'aide de l'encodeur d'échappement unicode.

>>> c.decode('unicode_escape')
'в'
45
Lennart Regebro

J'ai adoré la réponse de Lennart. Cela m'a mis sur la bonne voie pour résoudre le problème particulier que j'avais rencontré. Ce que j'ai ajouté, c'est la possibilité de produire du code compatible html pour\u ???? spécifications en chaînes. Fondamentalement, une seule ligne était nécessaire:

results = results.replace('\\u','&#x')

Tout cela est né d'un besoin de convertir les résultats JSON en quelque chose qui s'affiche bien dans un navigateur. Voici un code de test intégré à une application cloud:

# References:
# http://stackoverflow.com/questions/9746303/how-do-i-send-a-post-request-as-a-json
# https://docs.python.org/3/library/http.client.html
# http://docs.python-requests.org/en/v0.10.7/user/quickstart/#custom-headers
# http://stackoverflow.com/questions/606191/convert-bytes-to-a-python-string
# http://www.w3schools.com/charsets/ref_utf_punctuation.asp
# http://stackoverflow.com/questions/13837848/converting-byte-string-in-unicode-string

import urllib.request
import json

body = [ { "query": "co-development and language.name:English", "page": 1, "pageSize": 100 } ]
myurl = "https://core.ac.uk:443/api-v2/articles/search?metadata=true&fulltext=false&citations=false&similar=false&duplicate=false&urls=true&extractedUrls=false&faithfulMetadata=false&apiKey=SZYoqzk0Vx5QiEATgBPw1b842uypeXUv"
req = urllib.request.Request(myurl)
req.add_header('Content-Type', 'application/json; charset=utf-8')
jsondata = json.dumps(body)
jsondatabytes = jsondata.encode('utf-8') # needs to be bytes
req.add_header('Content-Length', len(jsondatabytes))
print ('\n', jsondatabytes, '\n')
response = urllib.request.urlopen(req, jsondatabytes)
results = response.read()
results = results.decode('utf-8')
results = results.replace('\\u','&#x') # produces html hex version of \u???? unicode characters
print(results)
1
SoothingMist