En Python API, existe-t-il un moyen d'extraire le point de code unicode d'un seul caractère?
Modifier: Au cas où cela serait important, j'utilise Python 2.7.
En Python API, existe-t-il un moyen d'extraire le point de code unicode d'un seul caractère?
Modifier: Au cas où cela serait important, j'utilise Python 2.7.
Il semble que 'ord()' fait ce que je veux : docs.python.org/library/functions.html#ord. Merci.
Si 'c' est ma variable de caractère (disons qu'elle est égale à ''), si je fais ucp = ord(c)
puis print ucp
, j'obtiens trois entiers, pas un seul entier. Comment obtenir un seul entier ?
Il s'avère que réussir à obtenir cela correctement est assez difficile : Python 2 et Python 3 présentent des problèmes subtils avec l'extraction des points de code Unicode à partir d'une chaîne.
Jusqu'à Python 3.3, il était possible de compiler Python dans l'un des deux modes :
sys.maxunicode == 0x10FFFF
Dans ce mode, les chaînes Unicode de Python prennent en charge la gamme complète des points de code Unicode de U+0000 à U+10FFFF. Un point de code est représenté par un élément de chaîne :
>>> import sys
>>> hex(sys.maxunicode)
'0x10ffff'
>>> len(u'\U0001F40D')
1
>>> [c for c in u'\U0001F40D']
[u'\U0001f40d']
C'est la valeur par défaut pour Python 2.7 sur Linux, ainsi que universellement pour Python 3.3 et ultérieur sur tous les systèmes d'exploitation.
sys.maxunicode == 0xFFFF
Dans ce mode, les chaînes Unicode de Python prennent en charge uniquement la gamme des points de code Unicode de U+0000 à U+FFFF. Tout point de code de U+10000 à U+10FFFF est représenté à l'aide d'une paire d'éléments de chaîne dans l'encodage UTF-16 :
>>> import sys
>>> hex(sys.maxunicode)
'0xffff'
>>> len(u'\U0001F40D')
2
>>> [c for c in u'\U0001F40D']
[u'\ud83d', u'\udc0d']
C'est la valeur par défaut pour Python 2.7 sur macOS et Windows.
Cette différence d'exécution rend l'écriture de modules Python pour manipuler des chaînes Unicode en tant que séries de points de code assez contraignante.
Pour résoudre cela, j'ai contribué à un nouveau module codepoints
à PyPI
:
https://pypi.python.org/pypi/codepoints/1.0
Ce module résout le problème en exposant des APIs pour convertir des chaînes Unicode en listes de points de code et vice versa, indépendamment du réglage sous-jacent de sys.maxunicode
:
>>> hex(sys.maxunicode)
'0xffff'
>>> snake = tuple(codepoints.from_unicode(u'\U0001F40D'))
>>> len(snake)
1
>>> snake[0]
128013
>> hex(snake[0])
'0x1f40d'
>>> codepoints.to_unicode(snake)
u'\U0001f40d'
Généralement, vous faites simplement ord(character)
pour trouver le point de code d'un caractère. Pour être exhaustif cependant, les caractères larges dans le Plan Multilingue Supplémentaire Unicode sont représentés par des paires de substitution (c'est-à-dire deux unités de code) dans les versions étroites de Python, alors dans ce cas, j'ai souvent besoin de faire ce petit contournement :
def get_wide_ordinal(char):
if len(char) != 2:
return ord(char)
return 0x10000 + (ord(char[0]) - 0xD800) * 0x400 + (ord(char[1]) - 0xDC00)
Ceci est rare dans la plupart des applications, donc normalement utilisez simplement ord()
.
Une paire de substitution n'est PAS "deux caractères". Il représente UN caractère. Elle se compose de deux points de code. Voir "point de code" et "type de point de code" dans unicode.org/glossary
@JohnMachin: Vous êtes proche, mais pas tout à fait : une paire de substitution reste tout simplement un seul point de code. Ce sont deux unités de code.
@Thanatos : Avez-vous réellement lu le lien que j'ai fourni ? Avez-vous suivi jusqu'au point de code D71 Haut-surronant : Un point de code Unicode dans la plage U+D800 à U+DBFF.
et l'équivalent bas D73 ?
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
E.g. pour '\u304f' je veux '304f'. Est-ce que c'est ce que fera 'ord()' ? Oui- docs.python.org/library/functions.html#ord
1 votes
Oui,
ord("\N{HIRAGANA LETTER KU}")
est en effet 12367, alias 0x304F. Je n'utiliserais jamais des chiffres pour les caractères comme vous le faites, seulement des caractères nommés comme je le fais. Les nombres magiques sont mauvais pour votre programme. Pensez simplement àchr
etord
comme des fonctions inverses l'une de l'autre. C'est vraiment facile.0 votes
@tchrist il pourrait être utile de noter que
chr
est l'opposé deord
en python 3.x, mais en python 2.xunichr
est l'inverse deord
carchr
ne fonctionne que pour des ordinaux jusqu'à 255 en python 2.x.0 votes
@David : Oui, mais je considère cela comme un système obsolète, qui ne fonctionne pas vraiment très bien pour Unicode - comme vous venez de le démontrer.
chr
etord
étaient toujours censés être inverses, et c'était un bug hérité de Python 2 qu'ils ne l'étaient parfois pas. C'est dingue.2 votes
@tchrist il y a encore beaucoup de personnes qui utilisent Python 2.x. Même en Python 3.x, il existe toujours des versions Unicode étroites (par exemple, la plupart des versions Windows de Python 3.x sont étroites). Je ne qualifierais pas la plupart des problèmes Unicode de la version 2.x de bugs, mais plutôt d'ajouts pour maintenir la compatibilité avec des scripts plus anciens ; Python 2.x fonctionne généralement bien avec Unicode. Python 3.0 rend cependant les choses beaucoup plus cohérentes en éliminant la différence entre
str
etunicode
.0 votes
Si
c
est ma variable de caractère (disons qu'elle est égale à ), si je faisucp = ord(c)
puisprint ucp
, j'obtiens trois entiers, pas un seul entier. Comment puis-je obtenir un seul entier ?0 votes
Dans le cas où cela importe, j'utilise Python 2.7.