Python DBF:';ascii';编解码器可以';在位置6对字节0xf6进行t解码:序号不在范围内(128)

Python DBF:';ascii';编解码器可以';在位置6对字节0xf6进行t解码:序号不在范围内(128),python,string,character-encoding,special-characters,dbf,Python,String,Character Encoding,Special Characters,Dbf,我有一个字符串,其中包含一个我想你会称之为“特殊”字符(上面有一个umlaut的o),它抛出了我正在使用的DBF库(Ethan Furman的Python DBF库retrieve_character()函数,函数最后一行的错误是“ascii”编解码器无法解码第6位的字节0xf6:序号不在范围内(128)) 守则: def retrieve_character(bytes, fielddef, memo, decoder): """ Returns the string in b

我有一个字符串,其中包含一个我想你会称之为“特殊”字符(上面有一个umlaut的o),它抛出了我正在使用的DBF库(Ethan Furman的Python DBF库
retrieve_character()
函数,函数最后一行的错误是
“ascii”编解码器无法解码第6位的字节0xf6:序号不在范围内(128)

守则:

def retrieve_character(bytes, fielddef, memo, decoder):
    """
    Returns the string in bytes as fielddef[CLASS] or fielddef[EMPTY]
    """
    data = bytes.tostring()
    if not data.strip():
        cls = fielddef[EMPTY]
        if cls is NoneType:
            return None
        return cls(data)
    if fielddef[FLAGS] & BINARY:
        return data
    return fielddef[CLASS](decoder(data)[0]) #error on this line

您是否尝试过使用
unicodeData.encode('ascii','ignore')
?这将把umlaut转换为
o
,同时忽略编码格式之间的任何转换错误。

dbf文件有一个代码页属性。听起来好像它没有正确地与文件一起设置。您知道使用哪个代码页创建数据吗?如果是,您可以在打开fi时覆盖dbf的设置乐:

table = dbf.Table('dbf_file', codepage='cp437')
cp437
只是一个例子——使用任何合适的方法

要查看dbf文件的当前代码页(假设在打开时未覆盖),请使用:

如果在打开文件时指定了错误的代码页,则非ascii数据可能不正确(例如,使用umlaut的o可能会以使用tilde的n结尾)。

这是我的方法。 dbf代码:您可以使用
re.findall
获取所有代码页

  • 标题
  • 伪代码:

    import dbf
    
    codepage_list = ['936', '437', ...]
    
    for codepage in codepage_list:
    
        tabel = dbf.Table('mydbf.dbf', codepage='cp{}'.format(codepage))
        tabel.open(dbf.READ_WRITE)
        try:
            for row in table: 
                print(row)
            table.close()
        except UnicodeDecodeError:
            print('wrong codepage', codepage)
            tabel.close()
            continue
    

    我想你要寻找的答案就在这一页上:从技术上讲,ASCII只包括0到127之间的7位值;如何解释高半边值一直是有争议的基本上已经取代了它。这看起来比您在原始问题中提出的问题要复杂得多。此外,bytes是一个保留字,没有tostring方法。data.strip()返回字符串,因此您的
    如果不是data.strip()
    行可能无法按您认为的方式工作…您的标志和二进制行是一个布尔运算,您的意思是这样的吗?为什么要使用NoneType然后返回None?什么是
    解码器
    ?第0个元素是什么?有趣的是,使用“cp437”抑制了错误,但我不确定程序现在是否正常工作。是否存在错误使用可能错误的代码页值时出现问题?@user2680039:Ppdated-answer。它说的是“ascii(普通的ol'ascii)”,这是我所期望的,因为您遇到了ascii错误。是什么程序创建了文件,以及当时的语言环境是什么?我不确定具体是什么程序创建的,也不确定您的意思是什么“locale”。然而,我比较了字段,似乎使用“cp437”是有效的。当我输出“data”时,它们在两种情况下看起来都一样(包括umlaut),只是现在它没有抛出错误。我将继续并标记为答案。
     ##
    Windows Encodings:
    874 Thai Windows
    932 Japanese Windows
    936 Chinese (PRC, Singapore) Windows
    949 Korean Windows
    950 Chinese (Hong Kong SAR, Taiwan) Windows
    1250 Eastern European Windows
    1251 Russian Windows
    1252 Windows ANSI
    1253 Greek Windows
    1254 Turkish Windows
    1255 Hebrew Windows
    1256 Arabic Windows
    MS-DOS Encodings:
    437 U.S. MS-DOS
    620 Mazovia (Polish) MS-DOS
    737 Greek MS-DOS (437G)
    850 International MS-DOS
    852 Eastern European MS-DOS
    857 Turkish MS-DOS
    861 Icelandic MS-DOS
    865 Nordic MS-DOS
    866 Russian MS-DOS
    895 Kamenicky (Czech) MS-DOS
    
    import dbf
    
    codepage_list = ['936', '437', ...]
    
    for codepage in codepage_list:
    
        tabel = dbf.Table('mydbf.dbf', codepage='cp{}'.format(codepage))
        tabel.open(dbf.READ_WRITE)
        try:
            for row in table: 
                print(row)
            table.close()
        except UnicodeDecodeError:
            print('wrong codepage', codepage)
            tabel.close()
            continue