【问题标题】:Replacing "\xe9" character from a unicode string in Python 3从 Python 3 中的 unicode 字符串替换“\xe9”字符
【发布时间】:2014-10-21 22:01:03
【问题描述】:

将 SublimeText 2.0.2 与 Python 3.4.2 一起使用,我得到一个带有 urllib 的网页:

response = urllib.request.urlopen(req)
pagehtml = response.read()

打印 => qualit\xe9">\r\n\t\t<META HTTP

我在 unicode 字符串中得到一个“\xe9”字符!

pagehtml 的标题告诉我它是用 ISO-8859-1 编码的 (Content-Type: text/html;charset=ISO-8859-1)。但是如果我用 ISO-8859-1 解码然后用 utf-8 编码,它只会变得更糟......

resultat = pagehtml.decode('ISO-8859-1').encode('utf-8')

打印 => qualit\xc3\xa9">\r\n\t\t<META HTTP

如何将所有 "\xe9"... 字符替换为对应的字母 ("é"...)?

编辑 1

我收到了UnicodeEncodeError(这就是我使用“utf-8”编码的原因)!

我应该提到我在 SublimeText 2.0.2 中运行我的代码。这似乎是我的问题。

编辑 2

它在 IDLE (Python 3.4.2) 和 OSX 终端 (Python 2.5) 中运行良好,但在 SublimeText 2.0.2 (使用 Python 3.4.2) 中不起作用... => 这似乎是一个SublimeText 控制台问题(输出窗口)而不是我的代码。

按照 J.F. Sebastian 的建议,我将查看 PYTHONIOENCODING env 看来我应该可以在sublime-build file 中设置它。

编辑 3 - 解决方案

我刚刚在sublime-build file 中添加了"env": {"PYTHONIOENCODING": "UTF-8"}。

完成。谢谢大家;-)

【问题讨论】:

  • 你是怎么打印的?
  • 无关:response.headers.get_content_charset() 返回 Content-Type HTTP 标头中指定的字符编码。
  • 你使用的是什么版本的 Sublime Text?
  • @MattDMo。崇高文本 2.0.2。我得到了解决方案。谢谢(请参阅帖子中的编辑)
  • sublime 构建文件的位置在哪里?

标签: macos python-3.x unicode character-encoding sublimetext


【解决方案1】:

响应是一个编码的字节串。解码即可:

>>> pagehtml = b'qualit\xe9'
>>> print(pagehtml)
b'qualit\xe9'
>>> print(pagehtml.decode('ISO-8859-1'))
qualité

【讨论】:

  • @Tibo,您的终端似乎没有针对特定编码进行配置,并且默认为不支持 é 字符的 ASCII。除了 SublimeText,您是否尝试过其他 IDE? Python 通常会检测输出窗口的编码并正确编码 Unicode 文本。应该有办法配置 SublimeText 报告其支持的编码,但我不熟悉。
  • 谢谢。确实,在 IDLE(Python 3.4.2)和 OSX 终端(Python 2.5)中没问题,但在 SublimeText(Python 3.4.2)中不起作用... => 这似乎是 SublimeText 控制台的问题(输出窗口) 而不是我的代码。我将按照 J.F. Sebastian 的建议查看“PYTHONIOENCODING 系统变量”。
【解决方案2】:

我很确定您实际上没有问题,除了理解字节与 unicode。事情正在按他们应该的方式运作。 pagehtml 是编码字节。 (我在您的第一行中用req = 'http://python.org' 确认了这一点。)当显示字节时,那些可以解释为可打印ascii 编码的字节会被打印出来,而其他字节则用十六进制转义符打印。 b'\xe9' 是 é 的单字节 ISO-8859-1 编码的十六进制转义编码,b'\xc3\xa9' 是其双字节 utf-8 编码的十六进制转义编码。

>>> b = b"qualit\xe9"
>>> u = b.decode('ISO-8859-1')
>>> u
'qualité'
>>> b2 = u.encode()
>>> b2
b'qualit\xc3\xa9'
>>> len(b) == 7 and len(b2) == 8
True
>>> b[6]
233
>>> b2[6], b2[7]
(195, 169)

所以pageuni = pagehtml.decode('ISO-8859-1') 将页面作为 unicode 提供给您。此解码执行您要求的替换。

【讨论】:

    【解决方案3】:

    我收到一个 UnicodeEncodeError(这就是我使用 'utf-8' 编码的原因)!我应该提到我在 SublimeText 中运行我的代码。这似乎是我的问题。有什么解决办法吗?

    不要手动编码,而是打印 unicode 字符串。

    适用于 Unix

    如果输出被重定向或语言环境(LANGUAGE、LC_ALL、LC_CTYPE、LANG)未配置(默认为 C (ascii)),则设置 PYTHONIOENCODING=utf-8。

    适用于 Windows

    如果内容可以使用控制台代码页表示,则设置 PYTHONIOENCODING=your_console_cp envvar,例如 PYTHONIOENCODING=cp1252(仅当它确实是您的控制台使用的编码时才将其设置为 cp1252,运行 chcp 进行检查)。或者使用 SublimeText 可以正确显示的任何编码,如果它没有打开控制台窗口来运行 Python 脚本。

    除非输出被重定向;如果直接从命令行运行脚本,则无需设置 PYTHONIOENCODING envvar。

    否则(为了支持无法在控制台编码中表示的字符),请安装 win_unicode_console package 并使用 python3 -mrun your_script.py 运行您的脚本或放在脚本的顶部:

    import win_unicode_console
    win_unicode_console.enable()
    

    它使用 Win32 API 如WriteConsoleW() 打印到控制台。您仍然需要配置正确的字体才能在控制台中看到任意 Unicode 文本。

    【讨论】:

    • 谢谢。 PYTHONIOENCODING 看起来很有希望。我一回家就检查一下。 (PS:我在 OSX 上,所以我猜 win_unicode_console 和 chcp 不适合我)。
    • @Tibo:我的大脑某处交叉了一些电线。为什么我认为您需要 Windows 解决方案,而您的输出建议使用 OSX 环境。好消息,它在 OSX 上更简单,如果输出被重定向或没有配置语言环境(LANGUAGE、LC_ALL、LC_CTYPE、LANG)(默认为 C(ascii)),只需设置PYTHONIOENCODING=utf-8。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 2017-07-26
    • 2019-01-24
    相关资源
    最近更新 更多