2009-04-07 2 views
35

у меня есть это:Как преобразовать Unicode в верхний регистр, чтобы распечатать его?

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

Что мне нужно сделать, чтобы напечатать:

EXÁMPLE 

(Там, где 'а' получает свой accute акцент, но в верхнем регистре.)

Я использую Python 2.6.

+2

py3k делает это правильно – SilentGhost

ответ

55

Я думаю, что это так просто, как не конвертировать в ASCII в первую очередь.

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

, если я делаю s = 'exámñple', как я могу напечатать s правильно в верхнем регистре? –

+0

Я имею в виду, как я могу преобразовать s в unicode без этой ошибки UnicodeDecodeError: 'ascii' codec can 't декодировать байт 0xa0 в позиции 2 (я использовал u' '+ s) –

+2

Это другой вопрос, но вы необходимо установить sysencoding в utf.Взгляните сюда: http://stackoverflow.com/questions/5419/python-unicode-and-the-windows-console/8020#8020 –

17

В python 2.x просто преобразуйте строку в unicode перед вызовом upper(). Используя код, который находится в формате UTF-8 на этой странице:

>>> 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 á 

Вызов decode берет его из текущего формата в Unicode. Затем вы можете преобразовать его в другой формат, например utf-8, с помощью кодирования. Если персонаж находился, скажем, iso-8859-2 (чешский и т. Д., В данном случае), вместо этого вы использовали бы s.decode('iso-8859-2').upper().

Как и в моем случае, если ваш терминал не является совместимым с unicode/utf-8, лучше всего вы можете надеяться, это либо шестнадцатеричное представление символов (например, мое), либо для его потери с использованием s.decode('utf-8').upper().encode('ascii', 'replace'), что приводит к "EX? MPLE. Если вы не можете сделать свой вывод в unicode, напишите вывод в файл в формате utf-8 и откройте его в своем любимом редакторе.

4

Я думаю, что есть немного фона мы пропускаем здесь:

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

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

Пока вы используете «Unicode» строки вместо «родной» строки, операторы, такие как верхние() будут работать с учетом unicode. FWIW, Python 3 использует unicode по умолчанию, делая различие в значительной степени несущественным.

Принимая строку из unicode в str, а затем обратно в unicode неоптимально во многих отношениях, и многие библиотеки будут производить Юникод выхода, если вы хотите; поэтому старайтесь использовать только объекты unicode для строк, если это возможно.

8

сначала, я использую только python 3.1 в эти дни; его центральная заслуга состоит в том, чтобы иметь неоднозначные байтовые строки из объектов Юникода. это делает подавляющее большинство текстовых манипуляций намного более безопасными, чем это имело место. взвешивая триллионы вопросов пользователей относительно проблем с кодированием python 2.x, соглашение python 2.1 u'äbc было просто ошибкой; с явным bytes и bytearray, жизнь становится намного проще.

Во-вторых, если py3k не ваш вкус, попробуйте пойти с from __future__ import unicode_literals, так как это будет имитировать поведение py3k на python 2.6 и 2.7. эта вещь избегала бы (легко совершенной) ошибки, которую вы делали, говоря print 'exámple'.upper(). по существу, это то же самое, что и в py3k: print('exámple'.encode('utf-8').upper()).сравнить эти версии (для py3k):

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

Первый из них, в основном, то, что вы делали, когда использовал голую строку 'exámple', если вы установите кодировку по умолчанию для utf-8 (в соответствии с произнесением BDFL, установкой по умолчанию кодирование во время выполнения - плохая идея, поэтому в py2 вам придется обмануть его, сказав import sys; reload(sys); sys.setdefaultencoding('utf-8'); я представляю лучшее решение для py3k ниже). когда вы смотрите на выходе из этих трех линий:

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

вы можете увидеть, что когда upper() был применен к первому тексту, он действовал на байтах, а не символы. python позволяет использовать метод upper() в байтах, но он определяется только для интерпретации байтов в US-ASCII. поскольку utf-8 использует значения в пределах 8 бит, но за пределами US-ASCII (от 128 до 255, которые не используются US-ASCII), на них не будет влиять upper(), поэтому, когда мы декодируем обратно вторая строка, мы получаем, что нижний регистр á. наконец, третья строка делает это правильно, и да, с удивлением, python, похоже, знает, что Á - это буква верхнего регистра, соответствующая á. я побежал быстрый тест, чтобы увидеть, какие символы питона 3 не конвертировать между заглавными и строчными буквами:

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

просматривал список показывает очень мало числа случаев латинских, кириллических или греческих буквы; большая часть выходных данных - неевропейские символы и знаки препинания. единственными символами, которые я обнаружил, что питон ошибался, - это Ԥ/ԥ (\ u0524, \ u0525, 'cyrillic {capital | small} letter pe с descender'), так что пока вы остаетесь за пределами латинских Extended-X блоков (проверьте их, они могут дать сюрпризы), вы можете использовать этот метод. конечно, я не проверял правильность отображений.

Наконец, вот что я вложил в мой раздел загрузки приложения py3k: метод, который переопределяет кодировку sys.stdout, видит с цифровыми символьными ссылками (NCRs) как резерв; это приводит к тому, что печать на стандартный вывод никогда не вызовет ошибку кодирования в юникоде. когда я работаю на ubuntu, _sys.stdout.encoding is utf-8; когда одна и та же программа запускается в окнах, это может быть что-то странное, как cp850. вывод может выглядеть starnge, но приложение работает без увеличения исключения на этих тусклых терминалах.

#=========================================================================================================== 
# 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() 

еще один совет: при тестировании, всегда пытаются print repr(x) или нечто подобное, что раскрывает личность x. все виды недоразумений могут возникнуть, если вы только print x в py2 и x - это либо строка октета, либо объект unicode. это очень озадачивает и склонно вызывать много царапин на голове. как я уже сказал, постарайтесь, по крайней мере, перейти к py26 с тем, что из будущего ввоза букв Unicode.

и закрыть, ссылаясь на цитату: "Символ Лефковиц говорит, что лучше в своей статье Encoding:

I believe that in the context of this discussion, the term "string" is meaningless. There is text, and there is byte-oriented data (which may very well represent text, but is not yet converted to it). In Python types, Text is unicode. Data is str. The idea of "non-Unicode text" is just a programming error waiting to happen."

обновление: только что питон 3 правильно преобразует S Строчная латинская буква LONG S к S, когда верхний регистр аккуратным. !

Смежные вопросы