Como posso converter Unicode para maiúsculas imprimi-lo?
-
05-09-2019 - |
Pergunta
eu tenho este:
>>> print 'example'
example
>>> print 'exámple'
exámple
>>> print 'exámple'.upper()
EXáMPLE
O que eu preciso fazer para imprimir:
EXÁMPLE
(Onde o 'a' recebe o seu sotaque accute, mas em letras maiúsculas.)
Eu estou usando Python 2.6.
Solução
Eu acho que é tão simples como não a conversão para ASCII em primeiro lugar.
>>> print u'exámple'.upper()
EXÁMPLE
Outras dicas
Em 2.x do Python, apenas converter a string para unicode antes de chamar superior (). Usando o seu código, que está em formato UTF-8 sobre esta página web:
>>> 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 á
A chamada para decode
leva-lo de seu formato atual para unicode. Você pode, em seguida, convertê-lo para algum outro formato, como utf-8, usando codificação. Se o personagem era, digamos, iso-8859-2 (Checa, etc, neste caso), você iria passar a usar s.decode('iso-8859-2').upper()
.
Como no meu caso, se o seu terminal não é unicode / UTF-8 em conformidade, o melhor que você pode esperar é tanto uma representação hexadecimal dos personagens (como o meu) ou para convertê-lo lossily usando s.decode('utf-8').upper().encode('ascii', 'replace')
, o que resulta em ' EX? mple'. Se você não pode fazer o seu show unicode terminal, escrever a saída para um arquivo no formato UTF-8 e aberto que no seu editor favorito.
Primeiro, eu só uso python 3.1 nos dias de hoje; o seu mérito central é ter cadeias de bytes disambiguated de objectos Unicode. isso faz com que a grande maioria das manipulações de texto muito mais seguro do que costumava ser o caso. pesando os trilhões de perguntas do usuário sobre problemas python 2.x codificação, a convenção u'äbc
de python 2.1 foi apenas um erro; com bytes
explícita e bytearray
, a vida fica muito mais fácil.
Em segundo lugar, se Py3k não é o seu sabor, em seguida, tentar ir com from __future__ import unicode_literals
, como o comportamento dessa vontade de Py3k mímico em python 2.6 e 2.7. essa coisa teria evitado o (facilmente comprometido) asneira que você fez ao dizer print 'exámple'.upper()
. essencialmente, este é o mesmo que no Py3k: print( 'exámple'.encode( 'utf-8' ).upper() )
. comparar estas versões (para Py3k):
print( 'exámple'.encode( 'utf-8' ).upper() )
print( 'exámple'.encode( 'utf-8' ).upper().decode( 'utf-8' ) )
print( 'exámple'.upper() )
O primeiro é, basicamente, o que você fez quando usou um 'exámple'
corda nua, desde que você definir o seu padrão codificação para utf-8
(de acordo com um pronunciamento BDFL, estabelecendo o padrão de codificação em tempo de execução é uma má idéia, portanto, em PY2 você vai ter que enganá-lo, dizendo import sys; reload( sys ); sys.setdefaultencoding( 'utf-8' )
; i apresentar uma solução melhor para Py3k abaixo). quando você olha para a saída destas três linhas:
b'EX\xc3\xa1MPLE'
EXáMPLE
EXÁMPLE
Você pode ver que quando upper()
foi aplicado ao primeiro texto, ele agiu em bytes, não em caracteres. pitão permite que o método upper()
em bytes, mas ela só é definido na interpretação US-ASCII de bytes. desde valores utf-8 utilizações in <> dentro 8 bits, mas fora de US-ASCII (128 até 255, que não são usados ??em US-ASCII), aqueles que não será afetados por upper()
, então quando nós decodificar volta na segunda linha, temos que minúscula á
. Finalmente, a terceira linha faz isso direito, e sim, surpresa, python parece estar ciente de que Á
é a letra maiúscula correspondente a á
. eu corri um teste rápido para ver o que personagens Python 3 não converter entre maiúsculas e minúsculas:
for cid in range( 3000 ):
my_chr = chr( cid )
if my_chr == my_chr.upper() and my_chr == my_chr.lower():
say( my_chr )
folheando a lista revela muito poucas incidências de latino, cirílico, ou letras gregas; maior parte da produção é caracteres não-europeus e pontuação. os únicos personagens eu poderia achar que python foi errado são ? / ? (\ u0524, \ u0525, 'cirílico {capitais | small} carta pe com descender'), por isso, enquanto você ficar fora dos latino blocos estendida-X ( confira os, eles podem produzir surpresas), que você pode realmente usar esse método. Claro, eu não verificar a exatidão dos mapeamentos.
Por último, aqui é o que eu colocar em minha seção de inicialização aplicação Py3k: um método que redefine o sys.stdout
codificação vê, com referências de caracteres numéricos (NCRs) como fallback; isso tem o efeito que a impressão para a saída padrão nunca vai levantar um erro de codificação Unicode. Quando eu trabalho no ubuntu, _sys.stdout.encoding
é utf-8
; quando o mesmo programa roda em Windows, que poderia ser algo singular como cp850
. os olhares, Poder saída starnge, mas o aplicativo é executado sem levantar uma exceção nesses terminais witted-dim.
#===========================================================================================================
# 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()
mais um conselho: ao testar, tente sempre print repr( x )
ou uma coisa semelhante que revela a identidade de x
. todos os tipos de mal-entendidos podem surgir se você apenas print x
em PY2 e x
ou é um octeto string ou um objeto unicode. é muito intrigante e propenso a causar uma série de cabeça-arranhão. Como eu disse, tentar mover pelo menos a py26 com que a partir futuro literais importação unicode encantamento.
E para fechar, citando uma citação: "Glyph Lefkowitz diz que é melhor em seu artigo Encoding :
Eu acredito que, no contexto desta discussão, o termo "string" é sem significado. Há um texto, e há é Bdados orientada a YTE (o qual pode muito bem representar texto, mas ainda não é convertido para ele). Em tipos de Python, Texto é unicode. Dados é str. A ideia de "texto não-Unicode" é apenas um erro esperando para acontecer de programação. "
atualização: acabou de encontrar python 3 corretamente convertidos s LATIN PEQUENA longa carta S para S quando maiúscula. puro!
Eu acho que há um pouco de fundo que estamos perdendo aqui:
>>> type('hello')
<type 'str'>
>>> type(u'hello')
<type 'unicode'>
Enquanto você estiver usando cordas "Unicode" em vez de cordas "nativos", os operadores gosto superior () irá operar com unicode em mente. FWIW, Python 3 usa Unicode por padrão, fazendo a distinção em grande parte irrelevante.
Como tirar uma seqüência de unicode
para str
e depois voltar para unicode
é abaixo do ideal em muitos aspectos, e muitas bibliotecas irá produzir saída unicode se quiser; de modo a tentar usar apenas objetos unicode
para cordas internamente sempre que puder.
Experimente:
s = 'exámple'
print unicode(s).upper()