Python における正規表現と sqlite3 への接続
Python を用いて web サイトを構築するにあたり,sqlite3 で作成したデータベースにアクセスすることがある.
このとき,sqlite3 における特殊文字の表現と Python における正規表現を明確に区別しておかないと,おかしな挙動を示すことになる.
. | ワイルドカード | |
^ | 行頭 | |
$ | 行末 | |
* | 直前の文字がないか,もしくは一つ以上ある | |
+ | 直前の文字が一つ以上ある | |
? | 直前の文字がないか,または一つだけある | |
[] | 指定した文字のどれか | |
| | いずれかの文字 | |
() | グループ化 |
これらの文字がsqlite3に保存されている場合,直接文字を指定してアクセスするとエラーを返す場合が多いはず.
そこで,これらの文字をPython内で単なる文字として扱う場合,バックスラッシュを付加すると良い.
つまり,\? のようにする.
そのためのメソッド.
import re def escape(self, s, quoted=u'.^$*+?', escape=u"\\": return re.sub(u'[%s]' % re.escape(quoted), lambda mo: escape + mo.group(), s)
sが対象の文字列,quoted に変換したい特殊文字を指定,escapeに特殊文字に追加する文字を指定.
上の例では, .^$*+? を \.\^\$\*\+\? にしている.
たとえば,"?joker+phoenix*"なんて文字があって,これをそのまま扱いたい場合,
str = "?joker+phoenix*" str_unicode = unicode(str, 'utf-8') str_escape = self.escape(str_unicode, quoted=u".^$*+?[]|()", escape=u"\\") print str_escape --- \?joker\+phoenix\*
となる.
さて,sqlite3 ではこういった特殊文字はどうなのか?
これはあまり詳しくないけれど,とりあえず,シングルクォーテーションは重ねておかないといけないようだ.
I'm a machine.
なんて言葉は
I''m a machine.
として保存されている.
だから,Python から sqlite3 に文字列を渡す場合,シングルクォーテーションは重ねておく必要がある.
よって,あらかじめ
str = self.escape(str, quoted=u"'", escape=u"'")
のように変更しておこう.
とりあえず,今のところ,これで幸せ.