NSPredicate で正規表現を利用する場合、全角文字の扱いに気をつけるべし
ざっくりまとめ
NSPredicate
で正規表現利用すると意外な挙動をする- 全角文字をうまく判定してくれない(半角としてあつかっている?)
- おとなしく
NSRegularExpression
を使いましょう
です。
環境
- Xcode v9.4.1
- Swift v4.1
問題
ちょっと正規表現使って、文字列のチェックをしたいなぁ〜とおもって、
NSPredicate
を使ってチェックしていたわけです。
let pattern = "^[a-z]+$"
let text = "abcde"
let predicate = NSPredicate(format: "SELF MATCHES %@", pattern)
if predicate.evaluate(with: text) {
// something
}
こういう感じですかね。
これはこれでちゃんと動くのですけど、
text に abcde(cが全角) を入れるとどうでしょう??
なんと true になるのです。。
仮に pattern を [0-9]
として text を 323921(9が全角) とすると...
これも true になります。。
では固定の文字列では?とおもい pattern を (foo|bar) とし text に foo(fが全角) をいれるとやっぱりこれも true ...
もしかして全角文字は無視されて判定されている?🤔
とかおもったので、「あ」とかを text にいれると false にちゃんとなるのです...。
結果から察するに、「半角に変換可能なものは半角にして実行している(あるいは半角として扱っている)」...っていうことでしょうか
対策
NSPredicate
ではなくて、 NSRegularExpression
を使いましょうっていうことです。
正規表現ってきたら、NSRegularExpression
こっちを脳死で選ぶぐらいでいいかと。
NSRegularExpression
の存在はもちろん知っていたのだけれど....
NSPredicate
でもできるんだ。しかもちょっと書き方楽だなぁ(NSRegularExpression
つかうとやりたいことの割にちょいめんどいw)
ってことで、つかってたんですけどね...
でもオプションかなんかがありそうなきがするんですよねぇ...なんとなく(見つけられなかったけど(汗))
だって、NSRegularExpression
ではちゃんと期待通りに動作しているわけですから
かるくソレ関連でググると、以前から同じことを言及しているものがあるので、最近出てきたっていうわけでもなさそうですね。。
英語圏なんかはいいだろうけど、日本語記事で NSPredicate
を紹介しているとこ全部にコメントして回りたい(笑)
参考
NSPredicate - Foundation | Apple Developer Documentation
Predicate Format String Syntax