【问题标题】:Dealing with wacky encodings in Python在 Python 中处理古怪的编码
【发布时间】:2011-02-28 13:27:43
【问题描述】:

我有一个 Python 脚本,它从许多来源(数据库、文件等)中提取数据。据说,所有字符串都是 unicode,但我最终得到的是以下主题的任何变化(由repr() 返回):

u'D\\xc3\\xa9cor'
u'D\xc3\xa9cor'
'D\\xc3\\xa9cor'
'D\xc3\xa9cor'

是否有可靠的方法来获取上述任意四个字符串并返回正确的 unicode 字符串?

u'D\xe9cor' # --> Décor

我现在能想到的唯一方法是使用eval()replace(),以及永远无法洗去的深深的、燃烧的耻辱。

【问题讨论】:

  • 没有古怪的编码,只有古怪的程序员。

标签: python unicode encoding character-encoding


【解决方案1】:

那只是UTF-8 data。使用.decode 将其转换为unicode

>>> 'D\xc3\xa9cor'.decode('utf-8')
u'D\xe9cor'

您可以对'D\\xc3\\xa9cor' 情况执行额外的字符串转义解码。

>>> 'D\xc3\xa9cor'.decode('string-escape').decode('utf-8')
u'D\xe9cor'
>>> 'D\\xc3\\xa9cor'.decode('string-escape').decode('utf-8')
u'D\xe9cor'
>>> u'D\\xc3\\xa9cor'.decode('string-escape').decode('utf-8')
u'D\xe9cor'

为了处理第二种情况,您需要先检测输入是否为unicode,然后将其转换为str

>>> def conv(s):
...   if isinstance(s, unicode):
...     s = s.encode('iso-8859-1')
...   return s.decode('string-escape').decode('utf-8')
... 
>>> map(conv, [u'D\\xc3\\xa9cor', u'D\xc3\xa9cor', 'D\\xc3\\xa9cor', 'D\xc3\xa9cor'])
[u'D\xe9cor', u'D\xe9cor', u'D\xe9cor', u'D\xe9cor']

【讨论】:

  • 它适用于特定情况。然而: u'D\\xc3\\xa9cor' --> u'D\\xc3\\xa9cor', u'D\xc3\xa9cor' --> UnicodeEncodeError, 'D\\xc3\\xa9cor' -- > u'D\\xc3\\xa9cor',
  • @Tyson:它不能适用于所有情况。如何确保'D:\\xc3\\xa9\\xc3xa9.png' 确实是 UTF-8 编码字符串,而不是 Windows 路径名?
  • 我可以假设我收到的所有数据都不是 Windows 路径名。
  • @Tyson:在评论中你说UnicodeEncodeError。请注意,它是 En 代码,而不是 De 代码。出于好奇:您是否在循环中(在控制台或窗口中)将其打印出来?这只是周一早上的疯狂猜测......
  • 为了调试,是的,我把它扔给stdout
【解决方案2】:

编写知道应将哪些转换应用于其源的适配器。

>>> 'D\xc3\xa9cor'.decode('utf-8')
u'D\xe9cor'
>>> 'D\\xc3\\xa9cor'.decode('string-escape').decode('utf-8')
u'D\xe9cor'

【讨论】:

    【解决方案3】:

    这是我在看到 KennyTM 正确、更简洁的解决方案之前得出的解决方案:

    def ensure_unicode(string):
        try:
            string = string.decode('string-escape').decode('string-escape')
        except UnicodeEncodeError:
            string = string.encode('raw_unicode_escape')
    
        return unicode(string, 'utf-8')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-04
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 1970-01-01
      • 2020-07-08
      相关资源
      最近更新 更多