NSPredicateの正規表現

NSPredicateでは正規表現もサポートしていて単にマッチングだけを目的とするのであれば、RegexKiOgreKitを導入する必要はありません。例えばURLマッチングであれば、

NSPredicate* reg = [NSPredicate predicateWithFormat:
  @"SELF MATCHES 'https?://[a-zA-Z0-9/.?_+~=%:;!#-]+'"];
if ([reg evaluateWithObject:source])
  {
     :
   }

のように簡単(正規表現自体の妥当性は置いといて...)にマッチするか否かを判定できます。残念ながらreplaceやキャプチャといったことはできないようですが判定だけが必要なケースであればアプリケーションを肥大化させることがないのでおすすめです。ただしICUの正規表現にはちょっとだけ落とし穴?があって、先の正規表現でもつい

NSPredicate* reg = [NSPredicate predicateWithFormat:
  @"SELF MATCHES 'https?://[\\w/.?+~=%:;!#-]+'"];

としてしまってマッチせず悩んだのですが、ここで躓く人が多いのでしょう、ちゃんとドキュメント

according to the ICU specification, regular expression metacharacters are not valid inside a pattern set.For example, the regular expression \d{9}[\dxX] does not match valid ISBN numbers (any ten digit number, or a string with nine digits and the letter 'X') since the pattern set ([\dxX]) contains a metacharacter (\d). Instead you could write an OR expression, ...

と書いてありました。メタキャラクタはセットの中では使えないんですね、ちょっと足下救われます。まあ、それぞれの方言なのでこのあたりは致し方ないです...(; ;)。ただ、代わりと言っては何ですがNSPredicateはCoreDataの抽出処理の中核にあるだけに正規表現以外のオペレータも充実していて、文字列であれば正規表現を使わなくとも

  • BEGINSWITH
  • ENDSWITH
  • CONTAINS
  • LIKE

などで十分代用できるケースも多々あるはずでで、パフォーマンス的にも有利な場合が多い気がします。ほかにもSQLライクなIN/BETWEENや、もちろんノーマル演算子=/!=/>/<なんかも使えます。面白いのは、case-insenstiveと(日本人にはあまり関係ないかもしれませんが)[d](diacritic-insenstive)なんていう指定もあって面白いです。

この記事のトラックバックURL:

http://hippos-lab.com/blog/trackback/314

Comments