如何解码cp1252字符串?

时间:2014-04-27 17:22:21

标签: python python-2.7 unicode encoding eyed3

我正在使用eyeD3获得一个mp3标签(ID V1),并想了解它的编码。这是我尝试的:

>>> print(type(mp3artist_v1))
<type 'unicode'>

>>> print(type(mp3artist_v1.encode('utf-8')))
<type 'str'>

>>> print(mp3artist_v1)
Zåìôèðà

>>> print(mp3artist_v1.encode('utf-8').decode('cp1252'))
Zåìôèðà 

>>> print(u'Zемфира'.encode('utf-8').decode('cp1252'))
Zемфира

如果我使用online tool对值进行解码,则会通过更改编码Zемфира和值{{}来表示值Zемфира可以转换为正确的值CP1252 → UTF-8 1}}通过更改Zåìôèðà等编码。

如何从CP1252 → CP1251获取Zемфираmp3artist_v1效果很好,但如何自动理解可能的编码(只需3次编码 - .encode('cp1252').decode('cp1251')cp1251cp1252?我打算使用以下代码:

utf-8

但它没有帮助,因为我应首先用一个字符集编码然后用另一个字符串解码。

1 个答案:

答案 0 :(得分:4)

s = u'Zåìôèðà'
print s.encode('latin1').decode('cp1251')
# Zемфира

说明:Zåìôèðà被错误地视为unicode字符串,而它实际上是一个字节序列,在cp1251中表示Zемфира。通过应用encode('latin1'),我们将此“unicode”字符串转换回字节,使用代码点编号作为字节值,然后将这些字节转换回unicode,告诉解码我们正在使用cp1251。

关于自动解码,以下蛮力方法似乎适用于您的示例:

import re, itertools

def guess_decode(s):
    encodings = ['cp1251', 'cp1252', 'utf8']

    for steps in range(2, 10, 2):
        for encs in itertools.product(encodings, repeat=steps):
            r = s
            try:
                for enc in encs:
                    r = r.encode(enc) if isinstance(r, unicode) else r.decode(enc)
            except (UnicodeEncodeError, UnicodeDecodeError) as e:
                continue
            if re.match(ur'^[\w\sа-яА-Я]+$', r):
                print 'debug', encs, r
                return r

print guess_decode(u'Zемфира')
print guess_decode(u'Zåìôèðà')
print guess_decode(u'ZåìôèðÃ\xA0')

结果:

debug ('cp1252', 'utf8') Zемфира
Zемфира
debug ('cp1252', 'cp1251') Zемфира
Zемфира
debug ('cp1252', 'utf8', 'cp1252', 'cp1251') Zемфира
Zемфира