ここに問題があります。Pythonsqliteクエリへの入力としてUnicode文字列があります。クエリは失敗しました(「いいね」)。文字列がわかります。「FRANCE」には6文字ではなく、7文字です。そして7番目はです。。。ユニコードU+FEFF、ゼロ幅のノーブレークスペース。
いったいどうやってそのようなもののクラスをクエリの前にトラップするのですか?
ここに問題があります。Pythonsqliteクエリへの入力としてUnicode文字列があります。クエリは失敗しました(「いいね」)。文字列がわかります。「FRANCE」には6文字ではなく、7文字です。そして7番目はです。。。ユニコードU+FEFF、ゼロ幅のノーブレークスペース。
いったいどうやってそのようなもののクラスをクエリの前にトラップするのですか?
PythonのUnicodeデータテーブルの一部としてunicodedataカテゴリを使用できます。
>>> unicodedata.category(u'a')
'Ll'
>>> unicodedata.category(u'.')
'Po'
>>> unicodedata.category(u',')
'Po'
ご覧のとおり、句読点の文字のカテゴリは「P」で始まります。したがって、charごとに(リスト内包表記を使用して)フィルターで除外する必要があります。
参照:
あなたの場合:
>>> 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'