Python3 完成 QUOTED-PRINTABLE 编码及反翻译

想生成一个vcf时遇到了从字符串到 Quoted Printable编码转换的问题

1. 从手机里导出的vcf是这样的格式:
BEGIN:VCARD
VERSION:2.1
N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:;=E5=B7=A5=E4=BC=9A=E7=9B=9F=E7=BB=8F=E6=B5=8E;;;
FN;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=E5=B7=A5=E4=BC=9A=E7=9B=9F=E7=BB=8F=E6=B5=8E
TEL;CELL:3000000100
END:VCARD
BEGIN:VCARD
VERSION:2.1
N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:;=E5=B7=A5=E4=BC=9A=E9=98=BF=E6=97=97=E5=B8=B8;;;
FN;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=E5=B7=A5=E4=BC=9A=E9=98=BF=E6=97=97=E5=B8=B8
TEL;CELL:3000000101
END:VCARD

2. 百度了一下, QUOTED-PRINTABLE是邮件常用的编码方式, python中有一个对应的模块   quopri
反编译:
In[189]:   quopri.decodestring('=E5=B7=A5=E4=BC=9A=E7=9B=9F=E7=BB=8F=E6=B5=8E').decode('utf-8')
Out[189]: '工会盟经济'
编译:
In[191]:   quopri.encodestring('工会盟经济'.encode())
Out[191]: b'=E5=B7=A5=E4=BC=9A=E7=9B=9F=E7=BB=8F=E6=B5=8E'

3. 然而, 进一步发现英文字符的处理有问题
In[192]: quopri.encodestring('Hello'.encode())
Out[192]: b'Hello'
这显然是不合理的

==> 百度到了这样的方法: bytes(engCharacter, encoding='unicode_escape').hex()   验证一下:
In[194]: bytes('Hello ', encoding='unicode_escape').hex()
Out[194]: '48656c6c6f20'

In[195]: quopri.decodestring('=48=65=6C=6C=6F=20=E5=B7=A5=E4=BC=9A=E7=9B=9F=E7=BB=8F=E6=B5=8E').decode('utf-8')
Out[195]: 'Hello 工会盟经济'

4. 看起来问题变得很简单了: 给我一段文本, 我拆分出中文的部分, 英文的部分, 以不同的方法编译再拼接就可以了
例如: 'Hello 工会盟经济', ''工会盟经济Hello '', 'He工会盟经济llo '
a) 先判断是否有非中文字符: '\u4e00' <= i <= '\u9fa5' :
     没有的话, 直接使用2里的  encodestring函数
     有的话, 中文部分使用quopri.encodestring; 英文使用 bytes(str, encoding='unicode_escape').hex(); 然后再拼接就可以了
          拆分很简单, engPartNameList = re.findall('[a-zA-Z]+',originalName) 即可提取出对应的英文字符串
          但是拼接很麻烦, 需要把engPartNameList 里的每个元素与originalName对应起来, 注意前后顺序; 而且还有一个风险, 很多字符集, 例如 空格, 中行线, 等

我在a这个牛角尖里想了一天, 终于想到了简单的方法b:

b) 将originalName里每个字符做了判断, 非中文字符, 就使用bytes函数, 中文字符, 就使用quopri.encodestring函数, 然后拼接即可

代码如下:

def engNameToQuoPriStr(engCharacter):    #非中文字符编码
    quotedPrintableName = '=' + bytes(engCharacter, encoding='unicode_escape').hex().upper()
    return quotedPrintableName

def chinNameToQuoPriStr(chinCharacter):    #非中文字符编码
    byteName = quopri.encodestring(chinCharacter.encode())
    quotedPrintableName = str(byteName)[2:-1]
    return quotedPrintableName

def UtfNameToQuoPriStr(realName):       
    quotedPrintableName = ''
    for i in realName:
        if '\u4e00' <= i <= '\u9fa5':
            quotedPrintableName += chinNameToQuoPriStr(i)
        else:
            quotedPrintableName += engNameToQuoPriStr(i)

    return quotedPrintableName

事后验证, 即使包含表情符也是正确的, 哈

你可能感兴趣的:(Python)