如何在Python中替换字符串中的无效unicode字符?

Reg*_*May 2 python string unicode character-encoding

据我所知,python的概念是在字符串中仅包含有效字符,但就我而言,操作系统将在我必须处理的路径名中提供带有无效编码的字符串。因此,我最终得到了包含非Unicode字符的字符串。

为了纠正这些问题,我需要以某种方式显示这些字符串。不幸的是,我无法打印它们,因为它们包含非Unicode字符。是否存在一种优雅的方式来替换这些字符,以至少对字符串的内容有所了解?

我的想法是逐字符处理这些字符串,并检查存储的字符是否实际上是有效的unicode。如果字符无效,我想使用某个unicode符号。但是我该怎么办呢?使用codecs似乎不适合该目的:我已经有一个由操作系统返回的字符串,而不是一个字节数组。将字符串转换为字节数组似乎涉及解码,这在我的情况下当然会失败。所以看来我被卡住了。

您对我有提示,如何创建这样的替换字符串?

Reg*_*May 5

感谢您的评论。这样我就能够实现更好的解决方案:

    try:
        s2 = codecs.encode(s, "utf-8")
        return (True, s, None)
    except Exception as e:
        ret = codecs.decode(codecs.encode(s, "utf-8", "replace"), "utf-8")
        return (False, ret, e)
Run Code Online (Sandbox Code Playgroud)

请分享该解决方案的任何改进。谢谢你!


Mar*_*ers 5

如果您有字节串(未编码的数据),请使用'replace'错误处理程序。例如,如果您的数据(大部分是)UTF-8编码的,则可以使用:

decoded_unicode = bytestring.decode('utf-8', 'replace')
Run Code Online (Sandbox Code Playgroud)

U + FFFD吗?将为无法解码的任何字节插入REPLACEMENT CHARACTER字符。

如果您想使用其他替换字符,那么以后很容易替换它们:

decoded_unicode = decoded_unicode.replace(u'\ufffd', '#')
Run Code Online (Sandbox Code Playgroud)

演示:

>>> bytestring = 'F\xc3\xb8\xc3\xb6\xbbB\xc3\xa5r'
>>> bytestring.decode('utf8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mjpieters/Development/venvs/stackoverflow-2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xbb in position 5: invalid start byte
>>> bytestring.decode('utf8', 'replace')
u'F\xf8\xf6\ufffdB\xe5r'
>>> print bytestring.decode('utf8', 'replace')
Føö?Bår
Run Code Online (Sandbox Code Playgroud)