2014-01-06 60 views
0

我正在使用Python的zipfile模块来提取可包含具有Unicode文件名的文件的.zip文件。 WinZip和7-Zip存档工作正常,但WinRAR对文件名进行编码的方式稍有不同。说我创建包含一个名为zip文件 “ - ★ - 私 - ”,以及与此提取它:Python:将Unicode代码点文件名转换为字符串

with zipfile.ZipFile(zip_file_path, 'r') as zf: 
    zf.extractall(extract_dir) 

这种提取物 “ - ★ - 私 - ” 作为 “ - #U2605-#U79c1-” 。 ZipInfo对象的文件名不是编码的,它只是一个包含输出文件名的常规ASCII字符串。

我想将包含Unicode代码点U-2605和U-79C1的字符串转换为有用的可输出Unicode字符串。所以我写了这个,但它不正确地转换字符:

string = codePoints.replace('#U', '\\u').encode('utf-8') 

无论如何,我在哪里错误地在这里?我没有得到同样的结果,如果我做了,我会得到:

string = '-\u2605-\u79c1-'.encode('utf-8') 

(假设的Python 3,在Python 2,我会前言以前的字符串以“U”字)

+1

这可能是因为'\\ u2605'与'\ u2605'不一样。 – Hyperboreus

+0

如果你想得到hacky,你实际上可以做这一步,然后通过一个使用“unicode_escape”编解码器进行解码的步骤(它将把所有这些“\ u2605”序列转换成\ u2605'字符) 。当然,如果你有任何真正的Unicode字符(就像你从更标准的zip文件中获得的那样),那么这将会失败,所以你需要做一个花哨的舞蹈来处理所有愚蠢的边缘情况...... – abarnert

+0

是的,我的错误与\\ u。 – wdep1

回答

1

我我不知道如果这是你在找什么:

>>> cp = '#U79c1' 
>>> chr(int(cp[2:],16)) 
'私' 

例如:

#! /usr/bin/python3 
import re 

def makeNice(s): 
    return re.subn('(#U[0-9a-f]{4})', lambda cp: chr(int(cp.groups()[0][2:],16)), s) [0] 

a = '-#U2605-#U79c1-' 
print(a, makeNice(a)) 

打印

-#U2605-#U79c1- -★-私- 
+0

看起来不错,谢谢;我考虑过正则表达式,但不确定它们是否是最佳解决方案。请注意,在Python 2上必须使用unichr()而不是chr()。 – wdep1

相关问题