如何应对你的前缀utf-8字符串(需要解码,但失败的'u`)?

时间:2016-09-08 11:40:53

标签: python python-2.7 unicode

我正在使用python构建一个兼容python 3的web基本文件管理器。

每个文件头都是:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import

然后我发现由于Unicode而出现了问题。

我的系统是中文,我有一个名为E:\filemanager\data\c - 副本的文件夹。

我使用ajax GET发送(E:\filemanager\data\c - 副本)到烧瓶应用(filemanager)。当我遇到指示路径不存在的Windows Error[3]时,我也会感到困惑。然后我使用pycharm调试我的代码,并在u'E:\\filemanager\\data\\c - \xe5\x89\xaf\xe6\x9c\xac'时看到字符串已经变为os.listdir(path)

这个字符串太可怕了。让我来说明问题:

>>> p1 = ur'E:\filemanager\data\c - 副本'
>>> p1
u'E:\\filemanager\\data\\c - \u526f\u672c'
>>> p1.encode('utf-8')
'E:\\filemanager\\data\\c - \xe5\x89\xaf\xe6\x9c\xac'
# here you can see this result just like p2 without `u` prefix

>>> p2 = u'E:\\filemanager\\data\\c - \xe5\x89\xaf\xe6\x9c\xac'
>>> p2.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\kasim\Envs\fmgr\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 24-29: ordinal not in range(128)

u中有一个p2前缀!这让我无法列出目录(因为名称错误)。

我知道只删除u前缀才能使解码成功。但如何删除它?

更新

我想要的是转换

u'E:\\filemanager\\data\\c - \xe5\x89\xaf\xe6\x9c\xac'

u'E:\\filemanager\\data\\c - \u526f\u672c''E:\\filemanager\\data\\c - \xe5\x89\xaf\xe6\x9c\xac'

由于\xe5\x89\xaf\xe6\x9c\xac前缀,

u无法解码,这是关键问题!

UPDATE2:

我的ajax代码:

function ajax2(options) {

  var querystring = options.params ? urllib.format({ query: options.params }) : ''

  if (options.loading)
    swalShowLoading();

  reqwest({
      url: options.url + querystring,
      contentType: 'application/json',
      method: options.method || 'GET',
      data: JSON.stringify(options.data)
  })

}

// getFileList
// because this is a `GET` method, so no data be JSON.stringify here
// sorry for wrong explanation before.
ajax2({
  url: ApiUrl.list,
  params: {
    path: encodeURI(path)
  },
  success:success,
  error:error
})

2 个答案:

答案 0 :(得分:1)

  

我想要的是转换

     

你&#39; E:\ filemanager \ data \ c - \ xe5 \ x89 \ xaf \ xe6 \ x9c \ xac&#39;到

     

你是E:\ filemanager \ data \ c - \ u526f \ u672c&#39;或者&#39; E:\ filemanager \ data \ c - \ xe5 \ x89 \ xaf \ xe6 \ x9c \ xac&#39;

     由于u前缀,

\ xe5 \ x89 \ xaf \ xe6 \ x9c \ xac无法解码,这是关键问题!

您无法解码Unicode字符串。关键问题是UTF-8编码的字节字符串首先被错误地解码了。

以下是如何扭转它,但你应该真正解决的是为什么开始时这是错误的。

latin1是一个编解码器,可将前256个Unicode代码点直接转换为字节:

>>> s = u'E:\\filemanager\\data\\c - \xe5\x89\xaf\xe6\x9c\xac'
>>> s.encode('latin1')
'E:\\filemanager\\data\\c - \xe5\x89\xaf\xe6\x9c\xac'

所以&#34;摆脱了你&#34;。您现在有一个可以使用UTF-8解码的字节字符串:

>>> s.encode('latin1').decode('utf8')
u'E:\\filemanager\\data\\c - \u526f\u672c'
>>> print s.encode('latin1').decode('utf8')
E:\filemanager\data\c - 副本

答案 1 :(得分:0)

unicode个字符串可以编码到字节str str可以解码unicode字符串。

如果u''import unicode_literals字符串文字,,则所有字符串文字都将是unicode个字符串。您只能编码那些,而不是decode。当您尝试decode已经解码的unicode字符串时,您获得的错误源于隐式转换。

>>> p1.encode('utf-8')
'E:\\filemanager\\data\\c - \xe5\x89\xaf\xe6\x9c\xac'

\x35…表示字符串的原始字节(str)。

u'E:\\filemanager\\data\\c - \xe5\x89\xaf\xe6\x9c\xac'

这是一个unicode字面值,字面上表达文字“\ xe5 ...” 如果您有原始字节表示,则需要确保Python将其视为str,而不是unicode

>>> p2 = b'E:\\filemanager\\data\\c - \xe5\x89\xaf\xe6\x9c\xac'
>>> p2.decode('utf-8')
u'E:\\filemanager\\data\\c - \u526f\u672c'

b前缀将文字标记为str,可将其解码为unicode

u'''' unicode_literals\u526funicodeencodestr
b''\xe5strdecodeunicode