代码之家  ›  专栏  ›  技术社区  ›  Stavros Korokithakis

如何检查Python unicode字符串以确定它*实际上*是正确的unicode?

  •  7
  • Stavros Korokithakis  · 技术社区  · 16 年前

    http://hub.iis.sinica.edu.tw/cytoHubba/

    很明显,这是各种各样的混乱,因为它被正确解码,但当我试图保存在postgres我得到:

    DatabaseError: invalid byte sequence for encoding "UTF8": 0xedbdbf
    

    在那之后,数据库闭口不谈,拒绝在没有回滚的情况下做任何事情,这将有点难以解决(长话短说)。有没有办法让我在它进入数据库之前检查它是否会发生?source.encode(“utf-8”)工作顺利,所以我不知道发生了什么。。。

    5 回复  |  直到 16 年前
        1
  •  9
  •   mikelikespie    16 年前

    有一个 缺陷 在Python2.x中,它只修复了Python3.x。事实上,这个bug甚至出现在OSX的iconv中(但不是glibc)。

    事情是这样的:

    Python2.x无法将UTF8代理项对[1]识别为无效(这就是您的字符序列)

    这个 应该

    foo.decode('utf8').encode('utf8')
    

    但多亏了他们没有修复的bug,它无法捕获代理对。

    在Python2.x中尝试这个,然后在3.x中尝试:

    b'\xed\xbd\xbf'.decode('utf8')
    

    它将在后者中(正确地)抛出一个错误。他们也没有在2.x分支中修复它。有关详细信息,请参见[2]和[3]

    [1] http://tools.ietf.org/html/rfc3629#section-4

    http://bugs.python.org/issue9133

    [3] http://bugs.python.org/issue8271#msg102209

        2
  •  1
  •   sth    16 年前

    蟒蛇 unicode 对象是一个Unicode码点序列,根据定义是正确的Unicode。蟒蛇 str 字符串是一个字节序列,可能是使用特定编码(UTF-8、拉丁语-1、Big5,…)编码的Unicode字符。

    source 是一个 物体或物体 字符串。 那个 source.encode("utf-8") 工作只是意味着你 转换 source.decode("utf-8") 失败。

    来源

    source = u'abc'
    call_db(source.encode('utf-8'))
    

    如果 来源 是一个 str公司 作为Utf-8以外的编码,您应该对该编码进行解码,然后将生成的Unicode对象编码为Utf-8:

    source = 'abc'
    call_db(source.decode('Big5').encode('utf-8'))
    
        3
  •  0
  •   chryss    16 年前

    你到底在干什么?内容确实解码得很好 utf-8 :

    >>> import urllib
    >>> webcontent = urllib.urlopen("http://hub.iis.sinica.edu.tw/cytoHubba/").read()
    >>> unicodecontent = webcontent.decode("utf-8")
    >>> type(webcontent)
    <type 'str'>
    >>> type(unicodecontent)
    <type 'unicode'>
    >>> type(unicodecontent.encode("utf-8"))
    <type 'str'>
    

    不过,请确保您理解Unicode字符串和utf-8编码字符串之间的区别。你需要发送到数据库的是 unicodecontent.encode("utf-8") webcontent ,但你解码来验证 不要

    正如沃尔夫所说,我确实要检查数据库和数据库连接的设置。

        4
  •  0
  •   Stavros Korokithakis    16 年前

        5
  •  0
  •   thanos    14 年前

    为了解决django/postgress的类似问题,我现在做了这样的事情

    class SafeTextField(models.TextField)
        def get_prep_value(self, value):
            encoded = base64.encodestring(value).strip()
            return super(SafeTextField, self).get_prep_value(encoded)
        def to_python(self, value):
            decoded = base64.decodestring(value)
            return super(SafeTextField, self).to_python(decoded)