Half Width Katakana の判定
def isNotHalfWidthKana(field_data, all_data): test = unicode(field_data, 'utf-8') KANA = range(65377, 65439) if len([c for c in test if ord(c) in KANA]) > 0: raise validators.ValidationError(_('Not Half-width Kana.'))
def isNotIncludeHalfWidthKana(field_data, all_data): test = unicode(field_data, 'utf-8') han_kana = re.compile(u'[\uFF61-\uFF9F]+') if han_kana.search(test) is not None: raise validators.ValidationError(_('Not Half-width Kana.'))
相変わらず、他人の話題に乗っかってばかりな訳ですが、自分ならこう書くかな。
_KANA = set(range(0xFF61, 0xFFA0)) def isNotIncludeHalfWidthKatakana(field_data, all_data): for c in (ord(c) for c in field_data.decode('utf-8')): if c in _KANA: raise validators.ValidationError(_('Not Half-width Kana.'))
list より set のがいいよね?パフォーマンス気にしすぎ?とりあえず Unicode 的には Half Width Katakana なのと isNot だと紛らわしいので、isNotIncludeHalfWidthKatakana に。
それはともかくとして range が終端を含まないのを忘れていると U+FF9F が通過してしまうオチが。境界値試験重要。まぁ、正規表現でもいいんだけど "+" はなくてもいいんじゃね。
あとこんなのもありか。Functional Programming スキーな人向け。
def empty(iterable): for i in iterable: return false return true _KANA = set(range(0xFF61, 0xFFA0)) def isNotHalfWidthKatakana(field_data, all_data): test = field_data.decode('utf-8') if not empty(c for c in test if ord(c) in _KANA): raise validators.ValidationError(_('Not Half-width Kana.'))
追記
ord を忘れていたので、追加。thanks id:perezvon さん。
しかし、ぼけてるなぁ。
再追記
正規表現エンジンはCで書かれているんだから Python で工夫するより正規表現使ったほうが早いよ、という話。うん、まあそりゃそうだ。でも以前書いたように
sum(itertools.repeat(1, 1000000))
とかが思いのほか早かったりするので、用意されている builtin function*1 と正規表現エンジン、あるいは psyco の有無とかでまたちょっと違う結果が出たりすることもあるかも。場合によっては pytst なんかのほうが適しているということも。IronPython とかだとどうかな。
でも Java だと正規表現エンジン自体も Pure Java だったりしてさてどうしたものか、というオチがあったりもする。
*1:なんで any とか all が builtin にないんだ?