这是问题所在,我有一个 unicode 字符串作为 python sqlite 查询的输入。查询失败('like')。原来字符串,'FRANCE' 没有 6 个字符,它有 7 个。第七个是。. . unicode U+FEFF,一个零宽度的不间断空格。
我到底如何在查询之前捕获一类这样的东西?
这是问题所在,我有一个 unicode 字符串作为 python sqlite 查询的输入。查询失败('like')。原来字符串,'FRANCE' 没有 6 个字符,它有 7 个。第七个是。. . unicode U+FEFF,一个零宽度的不间断空格。
我到底如何在查询之前捕获一类这样的东西?
您可以将 unicodedata 类别用作 Python 中 unicode 数据表的一部分:
>>> unicodedata.category(u'a')
'Ll'
>>> unicodedata.category(u'.')
'Po'
>>> unicodedata.category(u',')
'Po'
如您所见,标点字符的类别以“P”开头。因此,您需要逐个字符地过滤掉您(使用列表理解)。
也可以看看:
在你的情况下:
>>> unicodedata.category(u'\ufeff')
'Cf'
因此,您可以根据字符的类别执行一些白名单。
通常,如果您可以为您的用例定义这样的内容,则应使用允许字符的白名单来完成输入验证。然后,您只需丢弃不在白名单上的任何内容(或完全拒绝输入)。
如果您可以定义一组允许的字符,那么您可以使用正则表达式来删除其他所有内容。
例如,假设您知道“国家/地区”只有大写英文字母和空格,您可以删除其他所有内容,包括您讨厌的 unicode 字母,如下所示:
>>> import re
>>> country = u'FRANCE\ufeff'
>>> clean_pattern = re.compile(u'[^A-Z ]+')
>>> clean_pattern.sub('', country)
u'FRANCE'
如果您无法定义一组允许的字符,那么您将陷入大麻烦,因为您的任务是预测所有可能向您抛出的数以万计的意外 unicode 字符——并且越来越多的字符被添加到多年来,随着语言的发展,规范。
这也是字节顺序标记,BOM。只需先清理你的字符串以消除那些,使用类似的东西:
>>> f = u'France\ufeff'
>>> f
u'France\ufeff'
>>> print f
France
>>> f.replace(u'\ufeff', '')
u'France'
>>> f.strip(u'\ufeff')
u'France'