Unicode(西里尔文)字符索引,在python中重写

时间:2015-08-04 21:22:43

标签: python python-2.7 unicode

我正在使用西里尔字母拼写的俄语单词。除了str中有多少(但不是全部)西里尔字符被编码为两个字符外,一切正常。例如:

>>>print ["ё"]
['\xd1\x91']

如果我不想索引字符串位置或识别字符的位置并将其替换为另一个字符(例如"e",而没有分配),这不会成为问题。显然,2"字符"在使用前缀时被视为一个,如u"ё"

>>>print [u"ё"]
[u'\u0451']

但是str s作为变量传递,因此不能以u作为前缀,unicode()会给出UnicodeDecodeError(ascii编解码器可以'解码...)。

那么......我该如何解决这个问题呢?如果有帮助,我使用的是python 2.7

3 个答案:

答案 0 :(得分:2)

这里有两种可能的情况。

您的str代表有效的UTF-8编码数据,或者它不代表。

如果它表示有效的UTF-8数据,则可以使用mystring.decode('utf-8')将其转换为Unicode对象。在它是unicode实例之后,它将按字符而不是按字节索引,正如您已经注意到的那样。

如果它中包含无效的字节序列......你遇到了麻烦。这是因为“这个字节代表哪个字符?”的问题。不再有明确的答案。当你在UTF-8中实际上并不代表特定Unicode字符的字节序列中说“第三个字符”时,你将不得不确切地决定你的意思......

解决此问题的最简单方法可能是使用ignore_errors标记decode()。这将完全丢弃无效的字节序列,只给出字符串的“正确”部分。

答案 1 :(得分:1)

这些实际上是不同的编码:

>>>print ["ё"]
['\xd1\x91']
>>>print [u"ё"]
[u'\u0451']

您所看到的是列表中元素的__repr__。不是unicode对象的__str__版本。

  

但是strs作为变量传递,所以不可能   以u为前缀

您的意思是数据是字符串,需要转换为unicode类型:

>>> for c in ["ё"]: print repr(c)
...
'\xd1\x91'

您需要将双字节字符串强制转换为双字节宽度unicode:

>>> for c in ["ё"]: print repr(unicode(c, 'utf-8'))
...
u'\u0451'

你会看到这种转变,他们完全没问题。

答案 2 :(得分:1)

要将字节转换为Unicode,您需要知道相应的字符编码并调用bytes.decode

>>> b'\xd1\x91'.decode('utf-8')
u'\u0451'

编码取决于数据源。它可以是任何东西,例如,如果数据来自网页;见A good way to get the charset/encoding of an HTTP response in Python

不要在字节文字中使用非ascii字符(在Python 3中明确禁止)。添加from __future__ import unicode_literals以将所有"abc"文字视为Unicode文字。

注意:单个用户感知的字符可能跨越多个Unicode代码点,例如:

>>> print(u'\u0435\u0308')
ё