ちょっと前に書こうと思ってて忘れてたネタ。iOSアプリ内で正規表現を使ってごにょごにょしようと思ったらRegexKitLiteを導入するのが一番てっとりばやいのだけど、iOS 3.2以降はFoundation Framework内でも地味に正規表現が使えるようになってきてるのでメモがてら記事にしておく。

NSRegularExpressionSearch

Cocoaで文字列中に別な文字列が含まれているかどうかを知りたいときは、NSStringの-rangeOfString:というメソッドを使う。RubyのString#indexみたいな感じで、見付かった文字列がどこにあるかの位置を返してくれる。こんな感じ。

NSString *string = @"I love Udon.";
NSRange match = [string rangeOfString:@"Udon"];
if (match.location != NSNotFound) {
  NSLog(@"Found: %@",[string substringWithRange:match]);
} else {
  NSLog(@"Not Found");
}

これにもう少し細かく色々なオプションを指定できる-rangeOfString:options:というメソッドがあるのだけど、iOS3.2以上のバージョンだとこのオプションにNSRegularExpressionSearchというのが指定できるようになっている。実際に使うときはこう。

NSString *string = @"1日3食のうち4食はうどんを食べたいと思っている。";
NSRange match = [string rangeOfString:@"[0-9]+食" options:NSRegularExpressionSearch];
if (match.location != NSNotFound) {
  NSLog(@"Found: %@",[string substringWithRange:match]);
} else {
  NSLog(@"Not Found");
}

rangeOfString:に正規表現(の文字列)を渡せるようになってちょっと便利。書式はICU-comaptibleだそうだけど、RegexKitLiteもlibicucoreを使ってるので、RegexKitLiteを使ってた人は得に気にすることなく使えると思う。

これだけでも大分マシにはなったんだけど、さっきのサンプルコード見て分かる通り最初にマッチした部分しか取ってこれないし、もしかして-stringByReplacingOccurrencesOfString:withString:options:range:とかにも正規表現使えるのかなとwktkしたのだけど、「You can use this option only with the rangeOfString:... methods.」だそうで。マッチした箇所を全部取ってくるとか置換するとかは別な方法でやるようだ。

NSRegularExpression

さっきのはNSStringの文字列検索のオプションだったけど、正規表現そのものを扱うNSRegularExpressionというクラスがある。NSRegularExpressionSearchオプションは3.2以降であれば使えるけど、NSRegularExpressionクラスは4.0以降。つまり今までiPadでは使えなかったので、RegexKitLiteを置き換えるには至らなかった。

が。そろそろiPad版を含むiOS4.2がリリースされるので、ようやくiPadでも4系の機能が使えるようになるのです。弟の仇をトルノデス。ということで次回はNSRegularExpressionを使った文字列検索を記事にします。予告。