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

StackOverflow https://stackoverflow.com/questions/727507

Вопрос

У меня есть это:

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

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

EXÁMPLE

(Где буква "а" получает свое точное ударение, но в верхнем регистре.)

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

Это было полезно?

Решение

Я думаю, это так же просто, как не сначала преобразуйте в ASCII.

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

Другие советы

В python 2.x просто преобразуйте строку в юникод перед вызовом 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 переводит его из текущего формата в юникод.Затем вы можете преобразовать его в какой-либо другой формат, например utf-8, с помощью encode.Если бы символ был, скажем, в iso-8859-2 (в данном случае чешский и т.д.), вы бы вместо этого использовали s.decode('iso-8859-2').upper().

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

во-первых, в наши дни я использую только python 3.1;его главное достоинство заключается в устранении неоднозначности байтовых строк из объектов unicode.это делает подавляющее большинство текстовых манипуляций намного безопаснее, чем это было раньше.принимая во внимание триллионы вопросов пользователей, касающихся проблем с кодированием python 2.x, u'äbc соглашение python 2.1 было просто ошибкой;с явным 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, похоже, осознает, что Á соответствует ли заглавная буква á.я провел быстрый тест, чтобы увидеть, какие символы 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 )

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

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

#===========================================================================================================
# 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, используя это из будущего заклинания import unicode literals.

и в заключение процитирую цитату:" Глиф Лефковиц лучше всего говорит об этом в своей статье Кодирование:

Я полагаю, что в контексте этого обсуждения термин "строка" не имеет смысла.Есть текст, и есть данные, ориентированные на байты (которые могут очень хорошо представлять текст, но еще не преобразованы в него).В типах Python, Текст в формате unicode.Данные - это str.Идея "текста, отличного от Юникода", - это просто ожидающая своего появления ошибка программирования ".

Обновить:только что обнаружил, что python 3 корректно преобразует ſ ЛАТИНСКУЮ СТРОЧНУЮ БУКВУ ДЛИНОЙ S в S при использовании верхнего регистра.аккуратно!

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

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

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

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

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

Попробуй это:

s = 'exámple'
print unicode(s).upper()
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top