Python - 处理混合编码文件

2023-12-31

我有一个文件,大部分是 UTF-8,但也有一些 Windows-1252 字符。

我创建了一个表来将 Windows-1252 (cp1252) 字符映射到其 Unicode 对应字符,并希望使用它来修复错误编码的字符,例如

cp1252_to_unicode = {
    "\x85": u'\u2026', # …
    "\x91": u'\u2018', # ‘
    "\x92": u'\u2019', # ’
    "\x93": u'\u201c', # “
    "\x94": u'\u201d', # ”
    "\x97": u'\u2014'  # —
}

for l in open('file.txt'):
    for c, u in cp1252_to_unicode.items():
        l = l.replace(c, u)

但尝试以这种方式进行替换会导致引发 UnicodeDecodeError,例如:

"\x85".replace("\x85", u'\u2026')
UnicodeDecodeError: 'ascii' codec can't decode byte 0x85 in position 0: ordinal not in range(128)

关于如何处理这个问题有什么想法吗?


如果您尝试将此字符串解码为 utf-8,如您所知,您将收到“UnicodeDecode”错误,因为这些虚假的 cp1252 字符是无效的 utf-8 -

但是,Python 编解码器允许您注册处理编码/解码的回调 http://docs.python.org/library/codecs.html#codecs.register_errorg 错误,使用 codecs.register_error 函数 - 它获取 UnicodeDecodeerror 参数 - 您可以编写这样一个处理程序,尝试将数据解码为“cp1252”,并继续以 utf-8 格式解码字符串的其余部分。

在我的 utf-8 终端中,我可以构建一个混合的错误字符串,如下所示:

>>> a = u"maçã ".encode("utf-8") + u"maçã ".encode("cp1252")
>>> print a
maçã ma�� 
>>> a.decode("utf-8")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 9-11: invalid data

我在这里编写了上述回调函数,发现了一个问题:即使您将解码字符串的位置增加1,以便它从下一个字符开始,如果下一个字符也不是utf-8并且out范围 (128) 的情况下,在第一个超出范围 (128) 的字符处会引发错误 - 这意味着,如果找到连续的非 ascii、非 utf-8 字符,则解码将“返回”。

解决这个问题的方法是在 error_handler 中有一个状态变量,它检测到这种“走回来”并从上次调用它开始恢复解码 - 在这个简短的示例中,我将其实现为全局变量 - (必须手动每次调用解码器之前重置为“-1”):

import codecs

last_position = -1

def mixed_decoder(unicode_error):
    global last_position
    string = unicode_error[1]
    position = unicode_error.start
    if position <= last_position:
        position = last_position + 1
    last_position = position
    new_char = string[position].decode("cp1252")
    #new_char = u"_"
    return new_char, position + 1

codecs.register_error("mixed", mixed_decoder)

在控制台上:

>>> a = u"maçã ".encode("utf-8") + u"maçã ".encode("cp1252")
>>> last_position = -1
>>> print a.decode("utf-8", "mixed")
maçã maçã 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python - 处理混合编码文件 的相关文章

随机推荐

  • 将 Grunt 应用程序部署到 heroku 时,NPM 不会安装模块依赖项

    我使用 grunt 制作了一个静态单页网站 我现在尝试使用以下命令将其部署到 herokuheroku buildpack nodejs grunt https github com mbuchetics heroku buildpack
  • 已 root 的 Galaxy S8 上的设备所有者

    我一直在尝试将我的内部演示应用程序提升为设备所有者rootedS8 一直有问题 我尝试过的方法 1 NFC 配置 如所解释的here https github com googlesamples android NfcProvisionin
  • 如何使用应用密码访问bitbucket

    我已经按照说明创建了应用程序密码here https confluence atlassian com bitbucket app passwords 828781300 html 但现在 我如何使用此应用程序密码访问存储库 网址是什么 有
  • 使用 C 无法从 TCP 套接字正确接收数据 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我使用的是 Ubuntu 12 04
  • 如果字符串出现在源(或差异)中,Git 在提交之前发出警告

    当我在某个场所进行表演时 我希望能够被阻止 git如果我要提交的更改包含某个字符串 例如 todo or hack 有人可以告诉我如何实现这一目标吗 或警告 或在提交时 一个简单的预提交钩子检查是否添加了字符串 todo 如下所示 bin
  • Chrome 扩展和 Javasctipy 数据库

    我正在尝试构建一个 Chrome 扩展程序 该扩展程序将大量使用数据和图像 在存储数据时我有哪些选择 我希望我有某种 SQL 选项 SQLite 你可以去base64 http en wikipedia org wiki Base64编码图
  • 在后台打开新标签页?

    使用 javascript 我想在不同的选项卡中打开一个新页面 但仍将注意力集中在当前选项卡上 我知道我可以这样做 open http example com focus 但是 当我在 Chrome 中执行此操作时 它会在切换回当前选项卡之
  • 无法以编程方式更改 UITextView 框架大小

    我已使用界面生成器在视图中插入 UITextView 现在我想更改其框架大小 以便以编程方式适合内容 问题在于 由于限制 大小似乎被锁定并且无法从代码中更改 如果我在文件检查器中禁用自动布局 每个对象都会删除约束 但我只想更改 UIText
  • “UnicodeEncodeError:‘ascii’编解码器无法对字符进行编码”

    我试图通过正则表达式传递大的随机 html 字符串 而我的 Python 2 6 脚本对此感到窒息 UnicodeEncodeError ascii 编解码器无法对字符进行编码 我追溯到这个词末尾的商标上标 Protection 我希望将来
  • 如何交互 BlazorWebView 和 Windows 窗体

    我想将数据从 Windows 窗体发送到 BlazorWebView 并接收从 Web 视图返回到窗体的通知 这个怎么做 在 Net 6 Windows 窗体应用程序中 BlazorWebView blazorApp new BlazorW
  • iPhone 中用于 AES 加密的不同填充模式和密码模式有哪些?

    iPhone 中用于 AES 加密的不同填充模式和密码模式有哪些 Thanks 有两种填充模式 PKCS 7 和无 以及两种相应的密码模式 CBC 和 ECB 如果您指定kCCOptionPKCS7Padding然后你会得到 CBC 并且如
  • 如何在 MySQL 中使用准备好的语句截断表?

    这返回 true 但它没有截断表 this gt db gt query TRUNCATE TABLE tablename 但它在为准备好的语句创建数据库连接对象之前起作用 如何修复它 另外 我想知道如何使用准备好的语句截断表 NO 准备好
  • djangorest框架创建带有密码的用户

    使用 django rest framework 3 和 django 1 8 我正在尝试使用 django rest framework ModelViewSerializer 创建用户 问题是DRF使用的默认objects create
  • 如何在 PostgreSQL 中对使用 date_trunc 函数的表达式创建索引?

    当我尝试在 PostgreSQL 中对类型的表字段的表达式创建索引时date 使用date trunc函数 我收到以下错误 functions in index expression must be marked IMMUTABLE 我该如
  • Webpack 4 devtool 选项不适用于 webpack-dev-server

    在我决定发布这个问题之前 我做了很多事情作为背景调查 所以 我的问题是 我使用 webpack v4 6 0 和 webpack dev server v3 1 3 他们一起工作得很好 但现在我正在尝试为我的应用程序设置源映射 似乎开发工具
  • 如何续订 Azure API 管理证书

    使用我们的 Azure API 管理端点配置的证书今天过期了 显然它的有效期只有一年 我们如何更新它 我们认为使用 MS 提供的默认 API 管理证书意味着我们不必手动担心更新它 但事实似乎并非如此 证书过期消息 https i stack
  • 我的 VBA Excel 宏中的防病毒误报

    我刚刚遇到了一个更烦人的问题 https stackoverflow com questions 3339136 antivirus false positive in my executable 突然 Windows Defender 开
  • Netbeans7.1 和 JavaFX 2.0 - FXML 代码完成不起作用

    我开始学习 JavaFX 2 0 并安装了 Netbeans 7 1 java 7 02 SDK 其中包含 JavaFX 2 一切似乎都正常 示例项目编译并运行良好 我的问题是 代码完成不适用于 FXML 文件 我按 ctrl space
  • Matlab 快速傅立叶变换 / fft 用于时间和速度

    我有一个 2 列向量 其中包含数据子集的时间和速度 如下所示 5 40 10 37 15 34 20 39 等等 我想要对速度进行傅立叶变换以获得频率 我将如何使用快速傅里叶变换 fft 来做到这一点 如果我的矢量名称是sampleData
  • Python - 处理混合编码文件

    我有一个文件 大部分是 UTF 8 但也有一些 Windows 1252 字符 我创建了一个表来将 Windows 1252 cp1252 字符映射到其 Unicode 对应字符 并希望使用它来修复错误编码的字符 例如 cp1252 to