如何在Python中编写自定义编码以清理数据?

3 投票
1 回答
5231 浏览
提问于 2025-04-16 16:35

我知道我以前在其他工作中做过这件事,但现在想不起来我当时是怎么做的。

我有一个数据库,里面充满了从Office、网页和其他地方复制粘贴过来的varchar和memo字段。这开始让我遇到编码错误的问题。因为Python有一个很不错的“解码”功能,可以把字节流转换成Unicode,所以我想自己写一个编码来解决这个问题。(比如,把“智能引号”转换成“标准引号”。)

但我记不起来该怎么开始了。我想我复制了一个比较接近的编码(cp1252.py),然后进行了更新。

有没有人能给我指条明路?或者建议一个更好的方法?

1 个回答

3

我把内容扩展了一些,增加了细节。

如果你对数据库中文本的编码有一定把握,可以使用 text.decode('cp1252') 来得到一个Unicode字符串。如果猜错了,可能会出现错误,或者解码器会“消失”一些字符。

按照你描述的方式创建一个解码器(修改 cp1252.py)其实很简单。你只需要定义一个从字节到Unicode字符的转换表。

不过,如果数据库中的文本编码不一致,你的解码器就需要一些规则来判断哪个映射是正确的。在这种情况下,你可能想使用 chardet模块,它可以扫描文本并猜测编码。

也许最好的方法是先尝试用最可能的编码(cp1252)进行解码,如果失败了,再使用chardet来猜测正确的编码。

如果你使用 text.decode() 和/或 chardet,你最终会得到一个Unicode字符串。下面是一个简单的例程,可以在Unicode字符串中转换字符,比如“把弯引号转换成ASCII”:

CHARMAP = [
    (u'\u201c\u201d', '"'),
    (u'\u2018\u2019', "'")
    ]

# replace with text.decode('cp1252') or chardet
text = u'\u201cit\u2019s probably going to work\u201d, he said'

_map = dict((c, r) for chars, r in CHARMAP for c in list(chars))
fixed = ''.join(_map.get(c, c) for c in text)
print fixed

输出:

"it's probably going to work", he said

撰写回答