代码之家  ›  专栏  ›  技术社区  ›  Clay

如何将iso8859_6中的文件名转换为utf-8?

  •  0
  • Clay  · 技术社区  · 7 年前

    我收到了数千个Excel文件要处理。当我打开它们时,数据似乎是以一种我可以用Python读取和处理的方式编码的。

    但是,文件名已损坏。我将文件名导入sqlite,然后将它们的列表导出到CSV,以尝试使用正确的编码导入Excel。

    enter image description here

    如果我告诉Excel作为导入,名称就是这样显示的 28596: Arabic (ISO) iso8859_6 python 3.5编码。

    enter image description here

    enter image description here

    无论如何,如果我将这些文件名导入到Python中,我无法无误地对它们进行编码/解码。如果我将错误设置为 ignore 然后我看不到文件名。

    以下是它在Windows上的文件资源管理器和MacOS上的Finder中的显示示例。

    ½ñΘ Ω⌐αε δτßí ñáƒóƒ ƒΘª¼á ƒΘßá∩í Θ¼∞⌐ 4-2016.xlsx


    以下是我在代码中尝试的内容……我在sqlite数据库中有文件名,所以我从那里获取它们。(顺便说一句,我处理的99.9%的阿拉伯语都没有问题——只有这些文件名。)

    import dataset
    db = dataset.connect("sqlite:///mydata.sqlite")
    
    # Hit on one of the characters that appears in the garbled file names
    res = db.query("SELECT * FROM files WHERE file_name LIKE '%Ω%'")
    file_names = [r['file_name'] for r in res]
    test = file_names[0]
    print(test)
    
    >> '½ñΘ Ω⌐αε δτßí ñáƒóƒ ƒΘª¼á ƒΘßá∩í Θ¼∞⌐ 4-2016.xlsx'
    

    test.encode('iso8859_6')
    

    UnicodeEncodeError                        Traceback (most recent call last)
    <ipython-input-10-9c734319c359> in <module>()
    ----> 1 test.encode('iso8859_6')
    
    C:\ProgramData\Anaconda3\lib\encodings\iso8859_6.py in encode(self, input, errors)
         10 
         11     def encode(self,input,errors='strict'):
    ---> 12         return codecs.charmap_encode(input,errors,encoding_table)
         13 
         14     def decode(self,input,errors='strict'):
    
    UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-2: character maps to <undefined>
    

    尝试使用编解码器库

    import codecs
    codecs.encode(test,encoding='iso8859_6')
    

    与上述错误相同。

    codecs.encode(test,encoding='iso8859_6',errors='ignore')
    
    >> b'       4-2016.xlsx'
    

    codecs.encode(test,encoding='iso8859_6',errors='ignore').decode('utf-8')
    
    >> '       4-2016.xlsx'
    

    尝试另一种方法将其转换为字节,然后转换为iso格式:

    codecs.encode(test,encoding='utf-8',errors='ignore')
    
    >> b'\xc2\xbd\xc3\xb1\xce\x98 \xce\xa9\xe2\x8c\x90\xce\xb1\xce\xb5 \xce\xb4\xcf\x84\xc3\x9f\xc3\xad \xc3\xb1\xc3\xa1\xc6\x92\xc3\xb3\xc6\x92 \xc6\x92\xce\x98\xc2\xaa\xc2\xbc\xc3\xa1 \xc6\x92\xce\x98\xc3\x9f\xc3\xa1\xe2\x88\xa9\xc3\xad \xce\x98\xc2\xbc\xe2\x88\x9e\xe2\x8c\x90 4-2016.xlsx'
    

    与解码链接。。。

    codecs.encode(test,encoding='utf-8',errors='ignore').decode('iso8859_6')
    

    此错误:

    UnicodeDecodeError                        Traceback (most recent call last)
    <ipython-input-22-4a3c96284d09> in <module>()
    ----> 1 codecs.encode(test,encoding='utf-8',errors='ignore').decode('iso8859_6')
    
    C:\ProgramData\Anaconda3\lib\encodings\iso8859_6.py in decode(self, input, errors)
         13 
         14     def decode(self,input,errors='strict'):
    ---> 15         return codecs.charmap_decode(input,errors,decoding_table)
         16 
         17 class IncrementalEncoder(codecs.IncrementalEncoder):
    
    UnicodeDecodeError: 'charmap' codec can't decode byte 0xbd in position 1: character maps to <undefined>
    

    那么…也许这是错误的编码?

    老实说,我真的不知道该从哪里开始,因为我不太熟悉阿拉伯语的各种编码。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Blckknght    7 年前

    sqlite 数据库正在向您发送未正确解码的数据。它使用的是代码页437,而不是代码页720。您可以通过反转错误的编码,然后正确解码来修复此问题:

    filename = '½ñΘ Ω⌐αε δτßí ñáƒóƒ ƒΘª¼á ƒΘßá∩í Θ¼∞⌐ 4-2016.xlsx'
    filename_fixed = filename.encode('cp437').decode('cp720')
    print(filename_fixed) # prints "سجل مرضى نقطة جباتا الخشب الطبية لشهر 4-2016.xlsx"