python错误字符编码比较

python错误字符编码比较,python,encoding,Python,Encoding,Python中的西里尔字符比较有问题。这是一个小测试用例% #!/usr/bin/env python # -*- coding: utf-8 -*- def convert(text): result = [] for i in xrange(len(text)): if text[i].lower() == 'й': result.append('q') print result if __name__ == '__main

Python中的西里尔字符比较有问题。这是一个小测试用例%

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def convert(text):
    result = []
    for i in xrange(len(text)):
        if text[i].lower() == 'й':
            result.append('q')
    print result

if __name__ == '__main__':
    convert('йцукенг')
您肯定会看到,第一个字符应该等于条件中的字符。但条件失败,结果为空

另外,如果我尝试打印整个字符串(文本),效果会很好,但是如果我尝试只打印一个字符(如文本[2]),我会在输出中得到“?”


我确信问题在于编码,但如何正确比较单独的字符?

假定您使用的是Python 2.X,您应该使用unicode字符串,请尝试:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def convert(text):
    result = []
    for i in xrange(len(text)):
        if text[i].lower() == unicode('й', 'utf8'):
            result.append('q')
    print result

if __name__ == '__main__':
    convert(unicode('йцукенг', 'utf8'))

或者您可以简单地输入原始unicode字符串
u'ццццГ'
u'ц'

假设您使用的是Python 2.X,您应该使用unicode字符串,请尝试:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def convert(text):
    result = []
    for i in xrange(len(text)):
        if text[i].lower() == unicode('й', 'utf8'):
            result.append('q')
    print result

if __name__ == '__main__':
    convert(unicode('йцукенг', 'utf8'))

或者,您可以简单地输入原始unicode字符串
u'ццццГ'
u'ц'
,您看到这种行为是因为您在UTF-8字符串中的字节上循环,而不是在字符上循环。下面是一个不同的例子:

>>> 'й'               # note that this is two bytes
'\xd0\xb9'
>>> 'йцукенг'[0]      # but when you loop you are looking at a single byte
'\xd0'
>>> len('йцукенг')    # 7 characters, but 14 bytes
14
这就是为什么有必要使用Unicode来检查字符,就像mVChr的答案一样


要做到这一点,最简单的方法是保持所有代码完全相同,只需在所有字符串文本中添加一个
u
前缀(
u'цццццццГ'
u'ц'
)。

您看到这种行为是因为您在UTF-8字符串中循环字节,而不是在字符上循环。下面是一个不同的例子:

>>> 'й'               # note that this is two bytes
'\xd0\xb9'
>>> 'йцукенг'[0]      # but when you loop you are looking at a single byte
'\xd0'
>>> len('йцукенг')    # 7 characters, but 14 bytes
14
这就是为什么有必要使用Unicode来检查字符,就像mVChr的答案一样


要做到这一点,最简单的方法是保持所有代码完全相同,只需在所有字符串文本中添加一个
u
前缀(
u'ццццГ'
u'ц'
)。

您使用的终端是否支持这些字符?是的,整个字符串打印正确。我将每天发布几次此链接,直到不再需要:-此外,您的
for
循环只能是
for char in text:if char.lower()…
您使用的终端是否支持这些字符?是,整个字符串打印正确。我将每天发布几次此链接,直到不再需要:-此外,您的
for
循环可以是
for char in text:if char.lower()…
这假定他没有使用3.x。@Lattyware:问题中的代码示例是2.x。(注意不带括号的
print
语句。)@dan04你说得很好。我今天发现事情做得不好,就是这样!我使用2.6.1(刚刚安装在我的操作系统上),任务太小,无法安装其他任何东西。我必须一次又一次地理解编码处理,因为我经常遇到西里尔语,但我仍然一次又一次地遇到简单的问题。@AntonVernigor:请看我贴在问题上的链接作为评论-它应该可以帮助你理解这里发生的事情。这假设他没有使用3.x。@Lattyware:问题中的代码示例是2.x。(注意不带括号的
print
语句。)@dan04你说得很好。我今天发现事情做得不好,就是这样!我使用2.6.1(刚刚安装在我的操作系统上),任务太小,无法安装其他任何东西。我必须一劳永逸地理解编码处理,因为我经常遇到西里尔语,但我仍然一次又一次地遇到简单的问题。@AntonVernigor:请看我贴在问题上的链接作为评论-它应该可以帮助你理解这里发生了什么。