我有这个:
;gt;;gt;;gt; print 'example'
example
;gt;;gt;;gt; print 'exámple'
exámple
;gt;;gt;;gt; print 'exámple'.upper()
EXáMPLE
我需要做的打印:
EXáMPLE
(在" a"得到重音的地方,但大写。)
我正在使用Python 2.6。
py3k正确执行
我认为这就像不先转换为ASCII一样简单。
;gt;;gt;;gt; print u'exámple'.upper()
EXáMPLE
如果我做s = exmple,如何正确以大写形式打印s?
我的意思是,我如何在不使用此错误UnicodeDecodeError的Unicode中转换s:ascii编解码器无法解码位置2的字节0xa0(我在使用u + s)
这是另一个问题,但是您必须将sysencoding设置为utf。 在这里看看:stackoverflow.com/questions/5419/;hellip;
在python 2.x中,只需在调用upper()之前将字符串转换为unicode。使用此网页上的utf-8格式的代码:
;gt;;gt;;gt; s = 'exámple'
;gt;;gt;;gt; s
'ex\xc3\xa1mple' # my terminal is not utf8. c3a1 is the UTF-8 hex for á
;gt;;gt;;gt; 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格式写入文件,然后在您喜欢的编辑器中将其打开。
首先,这些天我只使用python 3.1;它的主要优点是可以从unicode对象中消除字节字符串的歧义。这使得绝大多数文本操作比以前更加安全。考虑到有关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似乎意识到á是与á相对应的大写字母。我进行了快速测试,以了解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,"带有后裔的西里尔字母{capital | small} pe pe"),因此,只要您不在Latin Extended-X块之外(请检查这些字母,它们可能会产生惊喜),您实际上可以使用该方法。当然,我没有检查映射的正确性。
最后,这是我在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的身份。如果您只是在py2中print x并且x是八位位组字符串或unicode对象,则会引起各种误解。这非常令人困惑,容易引起很多头疼。如我所说,尝试从将来的导入unicode字面量咒语至少迁移到py26。
并引用语录结尾:" Glyph Lefkowitz在他的文章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."
更新:刚发现python 3正确转换?大写时的拉丁文小写字母S到S。整齐!
我认为我们缺少一些背景知识:
;gt;;gt;;gt; type('hello')
;lt;type 'str';gt;
;gt;;gt;;gt; type(u'hello')
;lt;type 'unicode';gt;
只要您使用的是" unicode"字符串而不是" native"字符串,诸如upper()之类的运算符都会考虑到unicode。 FWIW,Python 3默认情况下使用unicode,这使得区分基本上无关紧要。
从unicode到str的字符串然后再回到unicode的字符串在许多方面都不理想。如果需要,许多库会产生unicode输出。因此,请尽可能在内部仅对字符串使用unicode对象。
试试吧:
s = 'exámple'
print unicode(s).upper()
这是一个已有八年历史的问题,它的答案已经被接受,顺便说一句,它与您的答案几乎完全相同。 我们这里可能需要的是可行的替代方案。 确保您的答案提供了这一点。