38 votes

Comment puis-je faire des majuscules Unicode?

J'ai ceci:

 >>> print 'example'
example
>>> print 'exámple'
exámple
>>> print 'exámple'.upper()
EXáMPLE
 

Ce que je dois faire pour imprimer:

 EXÁMPLE
 

(Où le «a» obtient son accent aigu, mais en majuscules.)

J'utilise Python 2.6.

60voto

tylerl Points 14541

Je pense que c'est aussi simple que de ne pas convertir en ASCII en premier.

  >>> print u'exámple'.upper()
 EXÁMPLE
 

18voto

Jarret Hardie Points 36266

En python 2.x, il suffit de convertir la chaîne de caractères au format unicode avant d'appeler un upper(). À l'aide de votre code, ce qui est au format utf-8 sur cette page:

>>> s = 'exámple'
>>> s
'ex\xc3\xa1mple'  # my terminal is not utf8. c3a1 is the UTF-8 hex for á
>>> s.decode('utf-8').upper()
u'EX\xc1MPLE'  # c1 is the utf-16 aka unicode for á

L'appel à l' decode prend sa forme actuelle en unicode. Ensuite, vous pouvez le convertir dans un autre format, comme utf-8, en utilisant l'encodage. Si le personnage a été, disons, iso-8859-2 (tchèque, etc, dans ce cas), vous devriez plutôt utiliser s.decode('iso-8859-2').upper().

Comme dans mon cas, si votre terminal n'est pas unicode/utf-8 conforme, le mieux que vous pouvez espérer, c'est une représentation hexadécimale des personnages (comme la mienne) ou à convertir lossily l'aide d' s.decode('utf-8').upper().encode('ascii', 'replace'), ce qui résulte en 'EX?MPLE''. Si vous ne pouvez pas vous rendre à votre terminal affiche unicode, écrire la sortie dans un fichier au format utf-8 et l'ouvrir dans votre éditeur préféré.

10voto

flow Points 1376

tout d'abord, je n'utilise python 3.1 ces jours-ci; son centre de mérite est d'avoir ambiguïté chaînes d'octets unicode objets. cela fait de la très grande majorité des textes des manipulations beaucoup plus sûr que l'habitude d'être le cas. pesant dans les milliers de milliards de questions des utilisateurs concernant python 2.x des problèmes de codage, l' u'äbc convention de python 2.1 était juste une erreur; explicite bytes et bytearray, la vie devient tellement plus facile.

deuxièmement, si py3k n'est pas à votre goût, alors essayez d'aller avec from __future__ import unicode_literals, ce qui permettra d'imiter py3k sur python 2.6 et 2.7. cette chose aurait évité l' (facilement engagé), bourde que vous avez fait quand dire print 'exámple'.upper() . essentiellement, c'est le même que dans py3k: print( 'exámple'.encode( 'utf-8' ).upper() ). comparer ces versions (pour py3k):

print( 'exámple'.encode( 'utf-8' ).upper() )
print( 'exámple'.encode( 'utf-8' ).upper().decode( 'utf-8' ) )
print( 'exámple'.upper() )

Le premier est que, fondamentalement, ce que lorsque vous avez utilisé une simple chaîne de caractères 'exámple', à condition que vous définissez votre encodage par défaut de utf-8 (selon une BDFL prononcé, le réglage de l'encodage par défaut au moment de l'exécution est une mauvaise idée, donc dans py2, vous aurez à le tromper en disant import sys; reload( sys ); sys.setdefaultencoding( 'utf-8' ); j'ai une meilleure solution pour py3k ci-dessous). lorsque vous chercher à la sortie de ces trois lignes:

b'EX\xc3\xa1MPLE'
EXáMPLE
EXÁMPLE

vous pouvez voir que lorsque l' upper() suis appliqué pour le premier texte, il a agi sur les octets, et non pas sur les personnages. python permet à l' upper() méthode sur des octets, mais il n'est définie que sur l'US-ASCII interprétation d'octets. depuis utf-8 utilise des valeurs au sein de 8 bits, mais en dehors de l'US-ASCII (128 à 255, qui ne sont pas utilisés par l'US-ASCII), ceux qui ne seront pas touchées par upper(), alors quand nous avons décoder de retour dans la deuxième ligne, nous obtenons que la baisse des cas á. enfin, la troisième ligne est-il de droite, et oui, surprise, python semble être conscient qu' Á est la lettre majuscule correspondante à l' á. j'ai couru un test rapide pour voir ce que les personnages python 3 n'est pas de convertir entre les majuscules et les minuscules:

for cid in range( 3000 ):
  my_chr = chr( cid )
  if my_chr == my_chr.upper() and my_chr == my_chr.lower():
    say( my_chr )

en parcourant la liste révèle que très peu d'incidences de latin, cyrillique, grec ou de lettres; la majorité de la production est non européen des caractères et des signes de ponctuation. les seuls personnages que j'ai pu trouver que python eu du mal Ԥ/ԥ (\u0524, \u0525, 'cyrillique {capitale|petit} lettre de pe avec la descendante'), donc tant que vous restez en dehors du Latin Extended-X blocs (admirez ces, ils pourraient donner des surprises), vous pouvez en fait utiliser cette méthode. bien sûr, je n'ai pas vérifier l'exactitude de la mappages.

enfin, voici ce que j'ai mis dans mon py3k application de démarrage de l'article: une méthode qui redéfinit le codage sys.stdout y voit, numériques références de caractère (Dnd) en remplacement; cela a pour effet que l'impression à la sortie standard, ne suscitera jamais une erreur de codage unicode. quand je travaille sur ubuntu, _sys.stdout.encoding est utf-8; si le programme fonctionne sur windows, il peut être quelque chose de pittoresque comme cp850. la sortie peut semble starnge, mais l'application s'exécute sans lever d'exception sur les dim-witted terminaux.

#===========================================================================================================
# MAKE STDOUT BEHAVE IN A FAILSAFE MANNER
#-----------------------------------------------------------------------------------------------------------
def _harden_stdout():
  """Ensure that unprintable output to STDOUT does not cause encoding errors; use XML character references
  so any kind of output gets a chance to render in a decipherable way."""
  global _sys_TRM
  _sys.stdout       = _sys_TRM = _sys_io.TextIOWrapper(
    _sys.stdout.buffer,
    encoding        = _sys.stdout.encoding,
    errors          = 'xmlcharrefreplace',
    line_buffering  = true )
#...........................................................................................................
_harden_stdout()

encore un conseil: lors de l'essai, essayez toujours d' print repr( x ) ou quelque chose de similaire qui révèle l'identité de l' x. toutes sortes de malentendus peuvent surgir si vous venez print x dans py2 et x est un octuor à cordes ou un objet unicode. il est très curieux et sujettes à causer beaucoup de casse-tête. comme je l'ai dit, essayez de passer au moins à py26 avec celle de l'avenir de l'importation de l'unicode des littéraux de l'incantation.

et pour finir, citant une citation: "Glyphe Lefkowitz en parle dans son article de l'Encodage:

Je crois que dans le contexte de cette la discussion, le terme de "chaîne" est pas de sens. Il y a du texte, et il n'y est-octets de données (qui peut très bien représenter le texte, mais n'est pas encore converties). En Python les types, Texte unicode. Les données sont str. L'idée de "non-Unicode texte n'est qu'un erreur de programmation en attente de se produire."

mise à jour: viens de trouver python 3 convertit correctement ſ LETTRE minuscule LATINE de LONGUES S de S quand uppercasing. neat!

5voto

tylerl Points 14541

Je pense qu'il y a un peu de fond qui nous manque ici:

>>> type('hello')
<type 'str'>

>>> type(u'hello')
<type 'unicode'>

Aussi longtemps que vous êtes à l'aide de "unicode" cordes à la place des "indigènes", les chaînes, les opérateurs comme upper() fonctionnera avec unicode à l'esprit. FWIW, Python 3 utilise unicode par défaut, la distinction largement hors de propos.

Prend une chaîne de caractère à partir d' unicode de str puis retour à l' unicode est sous-optimale dans de nombreuses façons, et de nombreuses bibliothèques produira unicode de sortie si vous le voulez; donc, essayez d'utiliser seulement unicode objets pour les chaînes en interne chaque fois que vous le pouvez.

Prograide.com

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.

Powered by:

X