38

我有这个:

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

我需要做的打印:

EXÁMPLE

(“a”的重音是大写的。)

我正在使用 Python 2.6。

4

5 回答 5

60

我认为这就像先转换为 ASCII 一样简单。

 >>> print u'exámple'.upper()
 EXÁMPLE
于 2009-04-07T20:45:53.403 回答
18

在 python 2.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'),这会导致 'EX?MPLE' . 如果您无法让终端显示 unicode,请将输出写入 utf-8 格式的文件,然后在您喜欢的编辑器中打开它。

于 2009-04-07T21:00:48.157 回答
10

首先,这些天我只使用 python 3.1;它的核心优点是从 unicode 对象中消除歧义的字节字符串。这使得绝大多数文本操作比以前更安全。考虑到关于 python 2.x 编码问题的数万亿用户问题,u'äbcpython 2.1 的约定只是一个错误;有了明确的bytesand 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 出错的唯一字符是 Ԥ /看看那些,他们可能会产生惊喜),你可能真的会使用那个方法。当然,我没有检查映射的正确性。

最后,这是我放入 py3k 应用程序启动部分的内容:一种重新定义编码的方法sys.stdout,使用数字字符引用 (NCR) 作为后备;这意味着打印到标准输出将永远不会引发 unicode 编码错误。当我在 ubuntu 上工作时,_sys.stdout.encodingutf-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 对象,则可能会出现各种误解。这是非常令人费解的,容易引起很多头疼。正如我所说,尝试至少从未来的导入 unicode 文字咒语中转移到 py26。

最后引用一句名言:“Glyph Lefkowitz 在他的文章Encoding中说得最好:

我相信在这个讨论的上下文中,术语“字符串”是没有意义的。有文本,还有面向字节的数据(可能很好地表示文本,但尚未转换为文本)。在 Python 类型中,Text 是 unicode。数据是str。“非 Unicode 文本”的想法只是一个等待发生的编程错误。”

更新:刚刚发现 python 3 在大写时正确地将 ſ LATIN SMALL LETTER LONG S 转换为 S。整洁的!

于 2010-09-11T16:52:59.607 回答
5

我认为我们在这里缺少一些背景知识:

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

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

只要您使用“unicode”字符串而不是“native”字符串,像 upper() 这样的运算符就会在使用 unicode 的情况下进行操作。FWIW,Python 3 默认使用 unicode,使得区别在很大程度上无关紧要。

unicodeto 获取字符串str然后再返回 tounicode在许多方面都不是最理想的,如果您需要,许多库会生成 unicode 输出;因此,请尽可能在unicode内部仅使用对象作为字符串。

于 2009-04-07T23:09:10.127 回答
-1

尝试一下:

s = 'exámple'
print unicode(s).upper()
于 2018-03-31T08:09:03.563 回答