NSPredicateでの正規表現について。その2 » サイキョウライン
え?なんなの?¥dと¥Dは全角半角関係ないの?どこ仕様?それどこ仕様よ?
ってことで、念のため仕様を追ってみました。
Predicate Format String Syntax
MATCHES
The left hand expression equals the right hand expression using a regex-style comparison according to ICU v3 (for more details see the ICU User Guide for Regular Expressions).
ここの「Regular Expressions」に付いてるリンクから、
Regular Expressions – ICU User Guide
\d ✓ ✓ Match any character with the Unicode General Category of Nd (Number, Decimal Digit.)
Regular Expressions – ICU User Guide
\D ✓ ✓ Match any character that is not a decimal digit.
「Unicode General Category of Nd (Number, Decimal Digit.)」ってなに?→ググる。
Unicode Characters in the ‘Number, Decimal Digit’ Category
U+0030 DIGIT ZERO 0
なるほどってことで、それぞれのコードを確認します。
NSLog(@"\\u%04x", [@"0" characterAtIndex:0]); //=> \u0030
NSLog(@"\\u%04x", [@"0" characterAtIndex:0]); //=> \uff10
んー、たしかに別物ですよねぇ。。。えぇ。。。
Unicode Characters in the ‘Number, Decimal Digit’ Category
U+FF10 FULLWIDTH DIGIT ZERO 0
。。。ん?
これもここにあるっていうことは「\d」の解釈は仕様として正しいってこと?「\d」を使ってるのがダメ?
NSPredicate *p1 = [NSPredicate predicateWithFormat:@"self matches '.*[^0-9]+?.*'"];
NSLog(@"%d", [p1 evaluateWithObject:@"1234567"]); //=> 0
NSLog(@"%d", [p1 evaluateWithObject:@"1234567"]); //=> 0
NSPredicate *p2 = [NSPredicate predicateWithFormat:@"self matches '.*[^0-9]+?.*'"];
NSLog(@"%d", [p2 evaluateWithObject:@"1234567"]); //=> 0
NSLog(@"%d", [p2 evaluateWithObject:@"1234567"]); //=> 0
ということは、この結果はどういうことなの?どう説明するの?
えー、だいぶ混乱してまいりました。
コメント
自分が理解している限りでは、\d みたいな記述は標準でも何でもなく、方言だと思われます(違うかもしれませんが)。方言なので普遍性は期待できず、ライブラリが変わった時の動作が保証されません。(前回のコメントで思わずキモいと書いてしまいましたがそれが念頭にありました。お気を悪くされていたらすみません)
そして、Number, Decimal Digit ([\p{Nd}]と表せます)にマッチする数字の種類は恐ろしく多いので、上に引用なさっている仕様のとおりの動作です。なにしろ漢数字のゼロ「〇」にすらマッチしてしまいます。
自分は正規表現のごく一部の文法だけを激しく使う日常ですが、複数環境で動作させないといけないために、最大公約数的な表現しか使わないようになりました。文字クラスを表す[\p{なんちゃら}]や[\u{20BA}]みたいな表記(これらすらライブラリで微妙に表記が違ってたりします)と先読み後読み以外はほとんど基本的な式しか使いません。
否定の [^なんちゃら] は割りと事故りやすいので、なるべく具体的に列挙するようにしています。
参考までに、自分が書いた記事の URL を貼っておきます http://qiita.com/hachi8833/items/71d5e2425bb447dc53c6
qiita読ませていただきました。
まさに数字の解釈を追いかけられていたのですね。
\dは[0-9]と同意と考えていたので、理解の間違えに気付くいい機会になりました。
さらに突っ込んでみたら原因がちょっと違う方向にありそうなので、別エントリとして書こうと思います。