Ale*_* S. 37 python unicode case-sensitive python-2.x uppercase
我有这个:
>>> print 'example'
example
>>> print 'exámple'
exámple
>>> print 'exámple'.upper()
EXáMPLE
Run Code Online (Sandbox Code Playgroud)
我需要做什么打印:
EXÁMPLE
Run Code Online (Sandbox Code Playgroud)
(其中'a'得到其精确的口音,但是大写.)
我正在使用Python 2.6.
tyl*_*erl 58
我认为这很简单,首先不转换为ASCII.
>>> print u'exámple'.upper()
EXÁMPLE
Run Code Online (Sandbox Code Playgroud)
Jar*_*die 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 á
Run Code Online (Sandbox Code Playgroud)
调用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'äbcpython 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() )
Run Code Online (Sandbox Code Playgroud)
第一个基本上是你使用裸字符串时所做的'exámple',只要你设置默认编码utf-8(根据BDFL声明,在运行时设置默认编码是个坏主意,所以在py2中你必须通过说法来欺骗它import sys; reload( sys ); sys.setdefaultencoding( 'utf-8' );我为下面的py3k提供了一个更好的解决方案.当你看看这三行的输出时:
b'EX\xc3\xa1MPLE'
EXáMPLE
EXÁMPLE
Run Code Online (Sandbox Code Playgroud)
你可以看到,当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 )
Run Code Online (Sandbox Code Playgroud)
仔细阅读清单显示拉丁语,西里尔语或希腊语字母的发生率很低; 大部分输出是非欧洲字符和标点符号.我发现python出错的唯一字符是Ԥ/ԥ(\ u0524,\ u0525,'cyrillic {capital | small}字母pe与descender'),所以只要你留在拉丁语Extended-X块之外(看看那些,他们可能会产生惊喜),你可能实际上使用那种方法.当然,我没有检查映射的正确性.
最后,这是我放入py3k应用程序引导部分的内容:重新定义编码的方法,sys.stdout数字字符引用(NCR)作为后备; 这会导致打印到标准输出永远不会引发unicode编码错误.当我在ubuntu上工作时,_sys.stdout.encoding是utf-8; 当相同的程序在Windows上运行时,它可能是古怪的东西cp850.输出可能看起来像starnge,但应用程序运行时没有在那些笨拙的终端上引发异常.
#===========================================================================================================
# 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()
Run Code Online (Sandbox Code Playgroud)
还有一条建议:在测试时,总是尝试print repr( x )或者类似的东西来揭示身份x.如果您只是print x在py2中并且x是一个八位字节字符串或一个unicode对象,那么就会出现各种各样的误解.这是非常令人费解的,容易引起很多人头疼.正如我所说,尝试使用未来的导入unicode文字咒语至少移动到py26.
并引用一句话来引用:"Glyph Lefkowitz在他的文章中说得最好编码:
我认为,在本次讨论的背景下,"字符串"一词毫无意义.有文本,并且有面向字节的数据(可能很好地代表文本,但尚未转换为它).在Python类型中,Text是unicode.数据是str."非Unicode文本"的想法只是一个等待发生的编程错误."
更新:刚刚发现python 3在大写时正确地将s LATIN SMALL LETTER LONG S转换为S. 整齐!
我认为我们在这里缺少一些背景:
>>> type('hello')
<type 'str'>
>>> type(u'hello')
<type 'unicode'>
Run Code Online (Sandbox Code Playgroud)
只要您使用“unicode”字符串而不是“本机”字符串,像 upper() 这样的操作符就会使用 unicode 进行操作。FWIW,Python 3 默认使用 unicode,这使得区别在很大程度上无关紧要。
从unicodeto取一个字符串str然后返回 tounicode在很多方面都是次优的,如果你想要的话,许多库会产生 unicode 输出;所以尽可能在unicode内部只使用字符串对象。