问题与.decode('utf-8')。upper()和特殊字符(但只在字符串内)

问题描述 投票:1回答:3

我想在字符串中给定位置上的字母大写。我有一个特殊字母的问题 - 波兰字母是特定的:例如“ą”。理想情况下,这种解决方案也适用于法语,西班牙语等。(ç,è等)

dobry="costąm"
print(dobry[4].decode('utf-8').upper())

我获得:

  File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)

UnicodeDecodeError: 'utf8' codec can't decode byte 0xc4 in position 0: unexpected end of data

虽然为此:

print("ą".decode('utf-8').upper())

我按照需要获得。。

对0-3位置的字母更感兴趣的是,它适用于:

print(dobry[5].decode('utf-8').upper())

我得到了同样的问题

python python-2.7 uppercase python-unicode polish
3个回答
3
投票

该字符串实际上如下所示:

>>> list(dobry)
['c', 'o', 's', 't', '\xc4', '\x85', 'm']

所以,dobry[5] == '\x85'因为字母±用两个字节表示。要解决这个问题,只需使用Python 3而不是Python 2。


2
投票

UTF-8可能使用多个字节来编码字符,因此迭代字节串并操纵单个字节并不总是有效。解码为Python 2的unicode类型更好。执行操作,然后重新编码为UTF-8。

>>> dobry="costąm"
>>> udobry = unicode(dobry, 'utf-8')
>>> changed = udobry[:4] + udobry[4].upper() + udobry[5]
>>> new_dobry = changed.encode('utf-8')
>>> print new_dobry
costĄm

正如@tripleee评论的那样,非ascii字符可能不会映射到单个unicode代码点:“±”可能是单个代码点U + 0105 LATIN SMALL LETTER A WITH OGONEK或者它可以由“a”组成,后跟U + 0328 COMBINING反尾形符。

在组合字符串中,“a”字符可以大写,“a”后跟COMBINING OGONEK将产生“Ą”(尽管它可能看起来像Python REPL中的两个单独字符,或者终端,具体取决于终端设置)。

请注意,索引时需要考虑额外的字符。

也可以使用unicodedata模块中的工具将组合字符串规范化为单个代码点(规范)版本:

>>> unicodedata.normalize('NFC', u'costa\u0328m') ==  u"costąm"
True

但是,如果您将更改后的字符串返回到需要保留组合字符的系统,则可能会出现问题。


1
投票

那又怎么样:

print(dobry.decode('utf-8')[5].upper())
© www.soinside.com 2019 - 2024. All rights reserved.