我有这个:
>>> print 'example'
example
>>> print 'exámple'
exámple
>>> print 'exámple'.upper()
EXáMPLE
我需要做的打印:
EXÁMPLE
(“a”的重音是大写的。)
我正在使用 Python 2.6。
我有这个:
>>> print 'example'
example
>>> print 'exámple'
exámple
>>> print 'exámple'.upper()
EXáMPLE
我需要做的打印:
EXÁMPLE
(“a”的重音是大写的。)
我正在使用 Python 2.6。
我认为这就像不先转换为 ASCII 一样简单。
>>> print u'exámple'.upper()
EXÁMPLE
在 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 格式的文件,然后在您喜欢的编辑器中打开它。
首先,这些天我只使用 python 3.1;它的核心优点是从 unicode 对象中消除歧义的字节字符串。这使得绝大多数文本操作比以前更安全。考虑到关于 python 2.x 编码问题的数万亿用户问题,u'äbc
python 2.1 的约定只是一个错误;有了明确的bytes
and 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.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 对象,则可能会出现各种误解。这是非常令人费解的,容易引起很多头疼。正如我所说,尝试至少从未来的导入 unicode 文字咒语中转移到 py26。
最后引用一句名言:“Glyph Lefkowitz 在他的文章Encoding中说得最好:
我相信在这个讨论的上下文中,术语“字符串”是没有意义的。有文本,还有面向字节的数据(可能很好地表示文本,但尚未转换为文本)。在 Python 类型中,Text 是 unicode。数据是str。“非 Unicode 文本”的想法只是一个等待发生的编程错误。”
更新:刚刚发现 python 3 在大写时正确地将 ſ LATIN SMALL LETTER LONG S 转换为 S。整洁的!
我认为我们在这里缺少一些背景知识:
>>> type('hello')
<type 'str'>
>>> type(u'hello')
<type 'unicode'>
只要您使用“unicode”字符串而不是“native”字符串,像 upper() 这样的运算符就会在使用 unicode 的情况下进行操作。FWIW,Python 3 默认使用 unicode,使得区别在很大程度上无关紧要。
从unicode
to 获取字符串str
然后再返回 tounicode
在许多方面都不是最理想的,如果您需要,许多库会生成 unicode 输出;因此,请尽可能在unicode
内部仅使用对象作为字符串。
尝试一下:
s = 'exámple'
print unicode(s).upper()