Python 如何将Unicode转换为大写来打印它?

Python 如何将Unicode转换为大写来打印它?,python,unicode,python-2.x,case-sensitive,uppercase,Python,Unicode,Python 2.x,Case Sensitive,Uppercase,我有这个: >>> print 'example' example >>> print 'exámple' exámple >>> print 'exámple'.upper() EXáMPLE 打印时需要执行的操作: EXÁMPLE (其中“a”的重音为accute,但为大写。) 我使用的是Python2.6。我认为这很简单,只要不首先转换为ASCII即可 >>> print u'exámple'.upper()

我有这个:

>>> print 'example'
example
>>> print 'exámple'
exámple
>>> print 'exámple'.upper()
EXáMPLE
打印时需要执行的操作:

EXÁMPLE
(其中“a”的重音为accute,但为大写。)


我使用的是Python2.6。

我认为这很简单,只要首先转换为ASCII即可

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

在Python2.x中,只需在调用upper()之前将字符串转换为unicode即可。使用此网页上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。然后可以使用encode将其转换为其他格式,如utf-8。如果字符是iso-8859-2(本例中为捷克语等),则应改用
s.decode('iso-8859-2').upper()


与我的情况一样,如果您的终端不符合unicode/utf-8,您最好希望的是字符的十六进制表示(如我的),或者使用
s.decode('utf-8').upper().encode('ascii','replace')
,将其进行无损转换,这将导致“示例”。如果您的终端无法显示unicode,请将输出写入utf-8格式的文件,然后在您最喜欢的编辑器中打开该文件。

我认为这里缺少一些背景信息:

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

>>> type(u'hello')
<type 'unicode'>
>>键入('hello')
>>>键入(u'hello')
只要您使用的是“unicode”字符串而不是“本机”字符串,像upper()这样的运算符就可以使用unicode进行操作。默认情况下,Python3使用unicode,这使得区别在很大程度上无关紧要


unicode
str
再返回到
unicode
的字符串在许多方面都是次优的,如果需要,许多库都会生成unicode输出;因此,尽可能在内部使用
unicode
对象作为字符串。

首先,我现在只使用python3.1;它的主要优点是从unicode对象中消除了字节字符串的歧义。这使得绝大多数文本操作比过去更加安全。考虑到用户对Python2.x编码问题提出的数万亿个问题,Python2.1的
u'228bc
约定只是一个错误;有了显式的
字节
字节数组
,生活变得轻松多了

其次,如果py3k不是您喜欢的,那么尝试使用来自未来导入unicode文本的
,因为这将模拟py3k在Python2.6和2.7上的行为。这本可以避免你在说
print'example'.upper()
时犯的(容易犯的)错误。本质上,这与py3k中的相同:
print('example'.encode('utf-8').upper())
。比较这些版本(对于py3k):

第一个是,基本上,当您使用一个裸字符串
'example'
时,如果您将默认编码设置为
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在大写和小写ca之间没有转换哪些字符se:

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加降序'),所以只要你不使用拉丁扩展X块(看看这些,它们可能会带来惊喜),你可能会实际使用这种方法。当然,我没有检查映射的正确性

最后,这里是我在py3k应用程序启动部分中介绍的内容:一种使用数字字符引用(NCR)重新定义编码
sys.stdout
sees的方法作为回退;这意味着打印到标准输出永远不会引起unicode编码错误。当我在ubuntu上工作时,
\u sys.stdout.encoding
utf-8
;当同一个程序在windows上运行时,它可能是像
cp850
这样的奇怪的东西。输出可能看起来是开始的,但应用程序运行时没有r在那些愚蠢的终端上是个例外

#===========================================================================================================
# 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()
还有一条建议:在测试时,始终尝试
打印repr(x)
或类似的东西,揭示了
x
的身份。如果你只是在py2中
print x
,并且
x
是一个八位字节字符串或unicode对象,就会产生各种各样的误解。这非常令人费解,而且容易引起很多人的挠头。正如我所说的,试着从未来的i开始,至少将其移动到py26输入unicode文字咒语

最后,引用一句话:“Glyph Lefkowitz在他的文章中说得最好:

我认为在这种情况下 在讨论中,术语“字符串”是 没有意义,有文字,有文字 是面向字节的数据(可能非常 我们可以表示文本,但还没有 在Python类型中, 文本是unicode。数据是str。这个想法 “非Unicode文本”只是一个 正在等待发生编程错误。“

更新:刚刚发现python 3在大写时正确地将ſ拉丁文小写字母长S转换为S。整洁!

试试:

s = 'exámple'
print unicode(s).upper()

如果我做s='exámñple',我怎么能
s = 'exámple'
print unicode(s).upper()