Python unicode 字符串被 psycopg 拒绝

标签 python postgresql unicode psycopg2

我从野外收到了一个 unicode 字符串,导致我们的一些 psycopg2 语句失败。

我已将问题简化为 SSCE:

import psycopg2
conn = psycopg2.connect(...)
cur = conn.cursor()
x = u'\ud837'
cur.execute("SELECT %s", (x,))
print cur.fetchone()

运行此命令会出现以下异常:

Traceback (most recent call last):
  File ".../run.py", line 65, in <module>
    cur.execute("SELECT %s AS test", (x,))
psycopg2.DataError: invalid byte sequence for encoding "UTF8": 0xed 0xa0 0xb7

根据一些评论,很明显这个特定角色是代理对的一半,使其无法单独生活。

具体来说,我正在寻找一种机制来检测 Python 2 中字符串何时包含不完整的代理对。

我发现一个导致异常的方法是尝试 x.encode('utf16').decode('utf16')但是,由于我不完全了解相关风险,因此我会有些担心。

编辑:将 SSCE 字符串减少为导致问题的单个字符,并根据注释添加信息。

最佳答案

字符串u'\ud837'surrogate pair的一个单独成员组成。 ,两个按顺序出现的物理字符形成一个逻辑字符。因此,它没有定义 Unicode 代码点 - 相反,它是 UTF-16 编码的实现细节,使用它将完整的代码点范围打包为 16 位代码单元。 Python 3 正确拒绝以任何字节编码(包括 UTF-* 变体)对单独代理进行编码的尝试。

该字符串可能源自内部使用 UTF-16 的系统(例如 Java、C#、Windows 或使用 16 位 Py_UNICODE 构建的 Python 2),该系统天真地缩短了该字符串而不小心代理人。

this answer 获取正则表达式,应该可以使用以下代码有效地检测此类字符串:

import re

lone = re.compile(
    ur'''(?x)            # verbose expression (allows comments)
    (                    # begin group
    [\ud800-\udbff]      #   match leading surrogate
    (?![\udc00-\udfff])  #   but only if not followed by trailing surrogate
    )                    # end group
    |                    #  OR
    (                    # begin group
    (?<![\ud800-\udbff]) #   if not preceded by leading surrogate
    [\udc00-\udfff]      #   match trailing surrogate
    )                    # end group
    ''')

def invalid_unicode(s):
    assert isinstance(s, unicode)
    return lone.search(s) is not None

关于Python unicode 字符串被 psycopg 拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40596209/

相关文章:

php - MySQL - 从 PHP 插入日语 - 编码问题

javascript - 匹配 JSON 字符串的正则表达式

python - 是否存在忽略多个错误并继续执行而不跳转的上下文?

sql - 使用转义换行符和回车符取消转义字符串

python - 如何计算来自不同列表的值的平均值

python - ArrayField 中的 Django JSONField

sql子查询加入分组依据

django - 如何在 Django 1.5 中获得对 rfc6532(电子邮件地址地址部分中的 unicode)的支持?

python - 在 Python 中获取异常值

python - 将 float 四舍五入到保留小数点后几位的最小数字