【问题标题】:How to replace invalid unicode characters in a string in Python?如何在 Python 中替换字符串中的无效 unicode 字符?
【发布时间】:2016-11-28 14:25:33
【问题描述】:

据我所知,python 的概念是在字符串中只包含有效字符,但在我的情况下,操作系统将在我必须处理的路径名中提供具有无效编码的字符串。所以我最终得到了包含非 unicode 字符的字符串。

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

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

您对我如何创建这样的替换字符串有什么建议吗?

【问题讨论】:

  • 请在您的问题中包含一个示例字符串;使用print repr(obj) 生成样本。您可能可以使用适当的errors 模式让 Python 为您插​​入占位符。
  • .decode("utf-8","ignore") 忽略坏字符。
  • 在 bash shell 中,我得到问号作为替换字符。在文件管理器中,我看到一个倒置的问号。
  • @RegisMay:是的,Python 可以给你一个类似的字符,但我想看看一些实际数据(所以我可以根据 type 调整我的答案例如,您拥有的数据)。

标签: python string unicode character-encoding


【解决方案1】:

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

decoded_unicode = bytestring.decode('utf-8', 'replace')

U+FFFD � REPLACEMENT CHARACTER字符将被插入任何无法解码的字节。

如果您想使用不同的替换字符,之后替换它们很容易:

decoded_unicode = decoded_unicode.replace(u'\ufffd', '#')

演示:

>>> 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

【讨论】:

  • 不错!我在文档中没有看到这一点:我希望这些功能能够被描述得更加突出。
【解决方案2】:

感谢您的 cmets。通过这种方式,我能够实施更好的解决方案:

    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)

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

【讨论】:

    【解决方案3】:

    你没有举个例子。因此,我考虑了一个示例来回答您的问题。

    x='This is a cat which looks good 😊'
    print x
    x.replace('😊','')
    

    输出是:

    This is a cat which looks good 😊
    'This is a cat which looks good '
    

    【讨论】:

    • 我没有关于在我的案例中导致错误的实际字节模式的具体示例。我正在编写的过滤器旨在识别给定字符串中的 Unicode 编码问题。您可能能够重现这种情况的一种方法是简单地生成随机数据,然后尝试将此数据解释为 UTF-8。您通常会失败,因为此二进制数据很可能违反 UTF-8 标准。抱歉,我无法确定这些违规行为是如何发生的。作为第一步,我试图确定那里的存在。
    • 如果不知道非 unicode 字符可以试试这个:try: string.decode('utf-8') print "string is UTF-8, length %d bytes" % len (string) except UnicodeError: print "string is not UTF-8"
    • 是的,但有趣的部分开始于我不仅想识别字符串是否为 Unicode,而且通过过滤或替换无效的“字符”来实际了解字符串本身..
    • 如果你能识别出无效的词,那么你只需替换那个词。
    【解决方案4】:

    正确的做法(至少在python2中)是使用unicodedata.normalize:

    unicodedata.normalize('NFKD', text).encode('utf-8', 'ignore')
    

    decode('utf-8', 'ignore') 只会引发异常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-20
      • 1970-01-01
      • 2018-04-12
      相关资源
      最近更新 更多