謂詞查詢

什么是謂詞查詢

  1. NSPredicate類是用來(lái)定義邏輯條件約束的獲取或內(nèi)存中的過(guò)濾搜索抑月。
  2. 可以使用謂詞表示邏輯條件,用于描述對(duì)象持久性存儲(chǔ)在內(nèi)存中的對(duì)象過(guò)濾衡便。

語(yǔ)法:

1.=绪妹、==:判斷兩個(gè)表達(dá)式是否相等,在謂詞中=和==是相同的意思都是判斷蚊夫,而沒(méi)有賦值這一說(shuō)

NSNumber *testNum = @180;
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = 180"];
  if ([predicate evaluateWithObject: testNum]) {
      NSLog(@"testString:%@", testNum);
  }

2.>=,=>:判斷左邊表達(dá)式的值是否大于或等于右邊表達(dá)式的值
3.<=止邮,=<:判斷右邊表達(dá)式的值是否小于或等于右邊表達(dá)式的值
4.>:判斷左邊表達(dá)式的值是否大于右邊表達(dá)式的值
5.<:判斷左邊表達(dá)式的值是否小于右邊表達(dá)式的值
6.!=这橙、<>:判斷兩個(gè)表達(dá)式是否不相等
7.BETWEEN:BETWEEN表達(dá)式必須滿足表達(dá)式 BETWEEN {下限奏窑,上限}的格式导披,要求該表達(dá)式必須大于或等于下限,并小于或等于上限

NSNumber *testNum = @180;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BETWEEN {100, 200}"];
  if ([predicate evaluateWithObject: testNum]) {
      NSLog(@"testString:%@", testNum);
  } else {
      NSLog(@"不符合條件");
  }

輸出打印

2017-01-07 11:20:39.921 PredicteDemo[4366:85408] testString:180

邏輯運(yùn)算符

AND埃唯、&&:邏輯與撩匕,要求兩個(gè)表達(dá)式的值都為YES時(shí),結(jié)果才為YES墨叛。
NSArray *testArray = @[@1, @2, @3, @4, @5, @6];
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF > 2 && SELF < 5"];
  NSArray *filterArray = [testArray filteredArrayUsingPredicate:predicate];
  NSLog(@"filterArray:%@", filterArray);

輸出結(jié)果為

2017-01-07 11:27:01.885 PredicteDemo[4531:89537] filterArray:(
3,
4
)

OR止毕、||:邏輯或,要求其中一個(gè)表達(dá)式為YES時(shí)漠趁,結(jié)果就是YES
    NOT扁凛、 !:邏輯非,對(duì)原有的表達(dá)式取反
字符串比較運(yùn)算符
    BEGINSWITH:檢查某個(gè)字符串是否以指定的字符串開(kāi)頭(如判斷字符串是否以a開(kāi)頭:BEGINSWITH 'a')
    ENDSWITH:檢查某個(gè)字符串是否以指定的字符串結(jié)尾
    CONTAINS:檢查某個(gè)字符串是否包含指定的字符串
    LIKE:檢查某個(gè)字符串是否匹配指定的字符串模板闯传。其之后可以跟?代表一個(gè)字符和*代表任意多個(gè)字符兩個(gè)通配符谨朝。比如"name LIKE '*ac*'",這表示name的值中包含ac則返回YES甥绿;"name LIKE '?ac*'"字币,表示name的第2、3個(gè)字符為ac時(shí)返回YES共缕。
    MATCHES:檢查某個(gè)字符串是否匹配指定的正則表達(dá)式洗出。雖然正則表達(dá)式的執(zhí)行效率是最低的,但其功能是最強(qiáng)大的图谷,也是我們最常用的翩活。
注:字符串比較都是區(qū)分大小寫和重音符號(hào)的。如:café和cafe是不一樣的便贵,Cafe和cafe也是不一樣的隅茎。如果希望字符串比較運(yùn)算不區(qū)分大小寫和重音符號(hào),請(qǐng)?jiān)谶@些運(yùn)算符后使用[c]嫉沽,[d]選項(xiàng)辟犀。其中[c]是不區(qū)分大小寫,[d]是不區(qū)分重音符號(hào),其寫在字符串比較運(yùn)算符之后堂竟,比如:name LIKE[cd] 'cafe'魂毁,那么不論name是cafe、Cafe還是café上面的表達(dá)式都會(huì)返回YES出嘹。
集合運(yùn)算符
    ANY席楚、SOME:集合中任意一個(gè)元素滿足條件,就返回YES税稼。
    ALL:集合中所有元素都滿足條件烦秩,才返回YES。
    NONE:集合中沒(méi)有任何元素滿足條件就返回YES郎仆。如:NONE person.age < 18只祠,表示person集合中所有元素的age>=18時(shí),才返回YES扰肌。
    IN:等價(jià)于SQL語(yǔ)句中的IN運(yùn)算符抛寝,只有當(dāng)左邊表達(dá)式或值出現(xiàn)在右邊的集合中才會(huì)返回YES。我們通過(guò)一個(gè)例子來(lái)看一下

例如

 NSArray *filterArray = @[@"ab", @"abc"];
  NSArray *array = @[@"a", @"ab", @"abc", @"abcd"];
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", filterArray];
  NSLog(@"%@", [array filteredArrayUsingPredicate:predicate]);
代碼的作用是將array中和filterArray中相同的元素去除曙旭,輸出為:

>2017-01-07 13:17:43.669 PredicteDemo[6701:136206] (
  a,
  abcd
)
        //array[index]:返回array數(shù)組中index索引處的元素
        //array[FIRST]:返回array數(shù)組中第一個(gè)元素
        //array[LAST]:返回array數(shù)組中最后一個(gè)元素
        //array[SIZE]:返回array數(shù)組中元素的個(gè)數(shù)
在謂詞表達(dá)式中可以使用如下直接量
    FALSE盗舰、NO:代表邏輯假
    TRUE、YES:代表邏輯真
    NULL桂躏、NIL:代表空值
    SELF:代表正在被判斷的對(duì)象自身
    "string"或'string':代表字符串
    數(shù)組:和c中的寫法相同钻趋,如:{'one', 'two', 'three'}。
    數(shù)值:包括證書剂习、小數(shù)和科學(xué)計(jì)數(shù)法表示的形式
    十六進(jìn)制數(shù):0x開(kāi)頭的數(shù)字
    八進(jìn)制:0o開(kāi)頭的數(shù)字
    二進(jìn)制:0b開(kāi)頭的數(shù)字
保留字
下列單詞都是保留字(不論大小寫)
AND蛮位、OR、IN进倍、NOT土至、ALL、ANY猾昆、SOME陶因、NONE、LIKE垂蜗、CASEINSENSITIVE楷扬、CI、MATCHES贴见、CONTAINS烘苹、BEGINSWITH、ENDSWITH片部、BETWEEN镣衡、NULL、NIL、SELF廊鸥、TRUE望浩、YES、FALSE惰说、NO磨德、FIRST、LAST吆视、SIZE典挑、ANYKEY、SUBQUERY啦吧、CAST您觉、TRUEPREDICATE、FALSEPREDICATE
注:雖然大小寫都可以丰滑,但是更推薦使用大寫來(lái)表示這些保留字

謂詞的用法

定義謂詞

一般我們使用下列方法來(lái)定義一個(gè)謂詞

NSPredicate *predicate = [NSPredicate predicateWithFormat:];

下面我們通過(guò)幾個(gè)簡(jiǎn)單的例子來(lái)看看它該如何使用:
首先我們需要定義一個(gè)模型顾犹,因?yàn)槭纠行枰玫剿?/p>

#import  "ZLPersonModel.h"
typedef NS_ENUM(NSInteger, ZLPersonSex) {
    ZLPersonSexMale = 0,
    ZLPersonSexFamale
};
 
@interface ZLPersonModel : NSObject
/** NSString 姓名 */
@property (nonatomic, copy) NSString *name;
/** NSUInteger 年齡 */
@property (nonatomic, assign) NSUInteger age;
/** ZLPersonSex 性別 */
@property (nonatomic, assign) ZLPersonSex sex;
 
+ (instancetype)personWithName:(NSString *)name age:(NSUInteger)age sex:(ZLPersonSex)sex;
 
@end

下面讓我們進(jìn)入正題
例一:(最簡(jiǎn)單的使用)

ZLPersonModel *sunnyzl = [ZLPersonModel personWithName:@"sunnyzl" age:29 sex:ZLPersonSexMale];
    ZLPersonModel *jack = [ZLPersonModel personWithName:@"jack" age:22 sex:ZLPersonSexMale];
    //  首先我們來(lái)看一些簡(jiǎn)單的使用
    //  1.判斷姓名是否是以s開(kāi)頭的
    NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"name LIKE 's*'"];
    //  輸出為:sunnyzl:1, jack:0
    NSLog(@"sunnyzl:%d, jack:%d", [pred1 evaluateWithObject:sunnyzl], [pred1 evaluateWithObject:jack]);
    //  2.判斷年齡是否大于25
    NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"age > 25"];
    //  輸出為:sunnyzl的年齡是否大于25:1, jack的年齡是否大于25:0
    NSLog(@"sunnyzl的年齡是否大于25:%d, jack的年齡是否大于25:%d", [pred2 evaluateWithObject:sunnyzl], [pred2 evaluateWithObject:jack]);

看到這里我們會(huì)發(fā)現(xiàn)evaluateWithObject:方法返回的是一個(gè)BOOL值倒庵,如果符合條件就返回YES,不符合就返回NO。而即使是最簡(jiǎn)單的使用也有一些大用處利赋,比如以前我們寫判斷手機(jī)號(hào)碼涡上、郵編等等,像我就喜歡用John Engelhart大神的RegexKitLite绍申,然而由于年代久遠(yuǎn)需要導(dǎo)入libicucore.dylib庫(kù)(xcode7為libicucore.tbd)且由于是mrc又需要添加-fno-objc-arc噩咪,至此我們才能使用。然而使用謂詞讓我們可以用同樣簡(jiǎn)潔的代碼實(shí)現(xiàn)相同的功能
例二:判斷手機(jī)號(hào)是否正確

 - (BOOL)checkPhoneNumber:(NSString *)phoneNumber
{
    NSString *regex = @"^[1][3-8]\\d{9}$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [pred evaluateWithObject:phoneNumber];
}

看到這里是不是感覺(jué)好爽极阅,感覺(jué)以前所有的正則都可以這么匹配胃碾,但是謂詞匹配正則時(shí)也是有缺點(diǎn)的,下面通過(guò)一個(gè)例子來(lái)看一下這個(gè)致命的缺點(diǎn)

- (BOOL)checkSpecialCharacter:(NSString *)string
{
    NSString *regex = @"[`~!@#$^&*()=|{}':;',\\[\\].<>/?~筋搏!@#¥……&*()——|{}【】‘仆百;:”“'。奔脐,俄周、?]";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [pred evaluateWithObject:string];
}

我們想要的效果是字符串中有特殊字符時(shí)就返回YES髓迎,然而夢(mèng)想是美好的峦朗,現(xiàn)實(shí)是殘酷的
讓我們看看這悲催的結(jié)局

NSString *testString = @"!";
NSLog(@"是否含有特殊字符:%d", [self checkSpecialCharacter:testString]);

// 當(dāng)testString為一個(gè)特殊字符時(shí),我們驚喜的發(fā)現(xiàn)輸出為
// 是否含有特殊字符:1
看到這里我們心里猛然一喜排龄,這tmd根本沒(méi)問(wèn)題嘛
讓我們修改下testString的值

NSString *testString = @"!~";
NSLog(@"%d", [self checkSpecialCharacter:testString]);
//  我們會(huì)發(fā)現(xiàn)悲催的結(jié)局來(lái)了輸出為
//  是否含有特殊字符:0
//再次修改testString的值
NSString *testString = @"abc!~d";
NSLog(@"%d", [self checkSpecialCharacter:testString]);

// 我們會(huì)發(fā)現(xiàn)輸出為
// 是否含有特殊字符:0
這總與我們的想法事與愿違波势,看到這里我們會(huì)發(fā)現(xiàn)謂詞對(duì)正則并不像我們使用NSRegularExpression時(shí)匹配的那么好,究其原因是為什么呢?我們用NSRegularExpression時(shí)會(huì)發(fā)現(xiàn)匹配到一個(gè)結(jié)果時(shí)就會(huì)存入數(shù)組尺铣,再?gòu)钠ヅ涞降奈恢美^續(xù)向下匹配闭翩。
然而NSPredicate并不會(huì)做這樣的自動(dòng)操作,我們最終發(fā)現(xiàn)在NSPredicate輸入[~!@#$^&*()=|{}':;',\[\].<>/?~迄埃!@#¥……&*()——|{}【】‘疗韵;:”“'。侄非,蕉汪、?]正則表達(dá)式時(shí)和寫成^[!@#$^&*()=|{}':;',[].<>/?逞怨!@#¥……&*()——|{}【】‘者疤;:”“'。叠赦,驹马、?]$的效果是一樣的除秀。
所以通過(guò)這個(gè)例子我們總結(jié)出來(lái)糯累,只有在正則表達(dá)式為^表達(dá)式$時(shí)才使用謂詞,而不是所有情況都使用册踩。
那么我們是不是因?yàn)檫@一點(diǎn)就摒棄它了呢泳姐,答案是否定的。因?yàn)殡m然NSPredicate有這么一點(diǎn)瑕疵暂吉,但是它總體帶給我們的便利其實(shí)除了正則表達(dá)式匹配時(shí)的這個(gè)問(wèn)題外是更多的胖秒。
2.使用謂詞過(guò)濾集合
此部分是我們需要掌握的重點(diǎn),因?yàn)閺倪@里我們就可以看到謂詞的真正的強(qiáng)大之處
其實(shí)謂詞本身就代表了一個(gè)邏輯條件慕的,計(jì)算謂詞之后返回的結(jié)果永遠(yuǎn)為BOOL類型的值阎肝。而謂詞最常用的功能就是對(duì)集合進(jìn)行過(guò)濾。當(dāng)程序使用謂詞對(duì)集合元素進(jìn)行過(guò)濾時(shí)肮街,程序會(huì)自動(dòng)遍歷其元素风题,并根據(jù)集合元素來(lái)計(jì)算謂詞的值,當(dāng)這個(gè)集合中的元素計(jì)算謂詞并返回YES時(shí)低散,這個(gè)元素才會(huì)被保留下來(lái)俯邓。請(qǐng)注意程序會(huì)自動(dòng)遍歷其元素,它會(huì)將自動(dòng)遍歷過(guò)之后返回為YES的值重新組合成一個(gè)集合返回熔号。
其實(shí)類似于我們使用tableView設(shè)置索引時(shí)使用的下段代碼

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    return [self.cityGroup valueForKey:@"title"];
}

中的[self.cityGroup valueForKey:@"title"]稽鞭。它的作用是遍歷所有title并將得到的值組成新的數(shù)組。
NSArray提供了如下方法使用謂詞來(lái)過(guò)濾集合

  • (NSArray*)filteredArrayUsingPredicate:(NSPredicate *)predicate:使用指定的謂詞過(guò)濾NSArray集合引镊,返回符合條件的元素組成的新集合
    NSMutableArray提供了如下方法使用謂詞來(lái)過(guò)濾集合
  • (void)filterUsingPredicate:(NSPredicate *)predicate:使用指定的謂詞過(guò)濾NSMutableArray朦蕴,剔除集合中不符合條件的元素
    NSSet提供了如下方法使用謂詞來(lái)過(guò)濾集合
  • (NSSet*)filteredSetUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0):作用同NSArray中的方法
    NSMutableSet提供了如下方法使用謂詞來(lái)過(guò)濾集合
  • (void)filterUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0):作用同NSMutableArray中的方法篮条。
    通過(guò)上面的描述可以看出,使用謂詞過(guò)濾不可變集合和可變集合的區(qū)別是:過(guò)濾不可變集合時(shí)吩抓,會(huì)返回符合條件的集合元素組成的新集合涉茧;過(guò)濾可變集合時(shí),沒(méi)有返回值疹娶,會(huì)直接剔除不符合條件的集合元素
    下面讓我們來(lái)看幾個(gè)例子:
    例一:
NSMutableArray *arrayM = [@[@20, @40, @50, @30, @60, @70] mutableCopy];
    //  過(guò)濾大于50的值
    NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"SELF > 50"];
    [arrayM filterUsingPredicate:pred1];
    NSLog(@"arrayM:%@", arrayM);
    NSArray *array = @[[ZLPersonModel personWithName:@"Jack" age:20 sex:ZLPersonSexMale],
                       [ZLPersonModel personWithName:@"Rose" age:22 sex:ZLPersonSexFamale],
                       [ZLPersonModel personWithName:@"Jackson" age:30 sex:ZLPersonSexMale],
                       [ZLPersonModel personWithName:@"Johnson" age:35 sex:ZLPersonSexMale]];
    //  要求取出包含‘son’的元素
    NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"name CONTAINS 'son'"];
    NSArray *newArray = [array filteredArrayUsingPredicate:pred2];
    NSLog(@"%@", newArray);

輸出為

2017-01-07 16:50:09.510 PredicteDemo[13660:293822] arrayM:(
60,
70
)
2017-01-07 16:50:09.511 PredicteDemo[13660:293822] (
"[name = Jackson, age = 30, sex = 0]",
"[name = Johnson, age = 35, sex = 0]"
)

從這個(gè)例子我們就可以看到NSPredicate有多么強(qiáng)大伴栓,如果讓我們用其他的方法來(lái)實(shí)現(xiàn)又是一大堆if...else。
讓我們來(lái)回顧一下上面的從第二個(gè)數(shù)組中去除第一個(gè)數(shù)組中相同的元素
例二:

   NSArray *filterArray = @[@"ab", @"abc"];
   NSArray *array = @[@"a", @"ab", @"abc", @"abcd"];
   NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", filterArray];
    NSLog(@"%@", [array filteredArrayUsingPredicate:predicate]);

輸出為:

2017-01-07 13:17:43.669 PredicteDemo[6701:136206] (
a,
abcd
)

如果我們不用NSPredicate的話雨饺,肯定又是各種if...else钳垮,for循環(huán)等等《罡郏可以看出NSPredicate的出現(xiàn)為我們節(jié)省了大量的時(shí)間和精力饺窿。
3.在謂詞中使用占位符參數(shù)
我們上面所有的例子中謂詞總是固定的,然而我們?cè)诂F(xiàn)實(shí)中處理變量時(shí)決定了謂詞應(yīng)該是可變的移斩。下面我們來(lái)看看如果讓謂詞變化起來(lái)肚医。
首先如果我們想在謂詞表達(dá)式中使用變量,那么我們需要了解下列兩種占位符:
%K:用于動(dòng)態(tài)傳入屬性名
%@:用于動(dòng)態(tài)設(shè)置屬性值
其實(shí)相當(dāng)于變量名與變量值
除此之外向瓷,還可以在謂詞表達(dá)式中使用動(dòng)態(tài)改變的屬性值肠套,就像環(huán)境變量一樣

NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF CONTAINS $VALUE"];

上述表達(dá)式中,$VALUE是一個(gè)可以動(dòng)態(tài)變化的值风罩,它其實(shí)最后是在字典中的一個(gè)key糠排,所以可以根據(jù)你的需要寫不同的值舵稠,但是必須有$開(kāi)頭超升,隨著程序改變$VALUE這個(gè)謂詞表達(dá)式的比較條件就可以動(dòng)態(tài)改變。
下面我們通過(guò)一個(gè)例子來(lái)看看這三個(gè)重要的占位符應(yīng)該如何使用
例一:

NSArray *array = @[[ZLPersonModel personWithName:@"Jack" age:20 sex:ZLPersonSexMale],
                     [ZLPersonModel personWithName:@"Rose" age:22 sex:ZLPersonSexFamale],
                     [ZLPersonModel personWithName:@"Jackson" age:30 sex:ZLPersonSexMale],
                     [ZLPersonModel personWithName:@"Johnson" age:35 sex:ZLPersonSexMale]];
  //  定義一個(gè)property來(lái)存放屬性名哺徊,定義一個(gè)value來(lái)存放值
  NSString *property = @"name";
  NSString *value = @"Jack";
  //  該謂詞的作用是如果元素中property屬性含有值value時(shí)就取出放入新的數(shù)組內(nèi)室琢,這里是name包含Jack
  NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K CONTAINS %@", property, value];
  NSArray *newArray = [array filteredArrayUsingPredicate:pred];
  NSLog(@"newArray:%@", newArray);
   
  //  創(chuàng)建謂詞,屬性名改為age落追,要求這個(gè)age包含$VALUE字符串
  NSPredicate *predTemp = [NSPredicate predicateWithFormat:@"%K > $VALUE", @"age"];
  // 指定$SUBSTR的值為 25    這里注釋中的$SUBSTR改為$VALUE
  NSPredicate *pred1 = [predTemp predicateWithSubstitutionVariables:@{@"VALUE" : @25}];
  NSArray *newArray1 = [array filteredArrayUsingPredicate:pred1];
  NSLog(@"newArray1:%@", newArray1);
   
  //  修改 $SUBSTR的值為32盈滴,  這里注釋中的SUBSTR改為$VALUE
  NSPredicate *pred2 = [predTemp predicateWithSubstitutionVariables:@{@"VALUE" : @32}];
  NSArray *newArray2 = [array filteredArrayUsingPredicate:pred2];
  NSLog(@"newArray2:%@", newArray2);

輸出為

2017-01-07 17:28:02.062 PredicteDemo[14542:309494] newArray:(
"[name = Jack, age = 20, sex = 0]",
"[name = Jackson, age = 30, sex = 0]"
)
2017-01-07 17:28:02.063 PredicteDemo[14542:309494] newArray1:(
"[name = Jackson, age = 30, sex = 0]",
"[name = Johnson, age = 35, sex = 0]"
)
2017-01-07 17:28:02.063 PredicteDemo[14542:309494] newArray2:(
"[name = Johnson, age = 35, sex = 0]"
)

從上例中我們主要可以看出來(lái)%K和$VALUE的含義。

實(shí)際應(yīng)用

簡(jiǎn)述:Cocoa框架中的NSPredicate用于查詢轿钠,原理和用法都類似于SQL中的where巢钓,作用相當(dāng)于數(shù)據(jù)庫(kù)的過(guò)濾取。
最常用到的函數(shù)

  • (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...;
    1.比較運(yùn)算符 > 疗垛、< 症汹、== 、 >= 贷腕、<= 背镇、 !=
    例:@"number >= 99"

2.范圍運(yùn)算符:IN 咬展、BETWEEN
例:@"number BETWEEN {1,5}"
@"address IN {'shanghai','nanjing'}"

3.字符串本身:SELF
例:@"SELF == 'APPLE'"

4.字符串相關(guān):BEGINSWITH、ENDSWITH瞒斩、CONTAINS
例:@"name CONTAIN[cd] 'ang'" //包含某個(gè)字符串
@"name BEGINSWITH[c] 'sh'" //以某個(gè)字符串開(kāi)頭
@"name ENDSWITH[d] 'ang'" //以某個(gè)字符串結(jié)束
注:[c]不區(qū)分大小寫 , [d]不區(qū)分發(fā)音符號(hào)即沒(méi)有重音符號(hào) , [cd]既不區(qū)分大小寫破婆,也不區(qū)分發(fā)音符號(hào)。

5.通配符:LIKE
例:@"name LIKE[cd] 'er'" //代表通配符,Like也接受[cd].
@"name LIKE[cd] '???er
'"

6.正則表達(dá)式:MATCHES
例:NSString *regex = @"^A.+e$"; //以A開(kāi)頭胸囱,e結(jié)尾
@"name MATCHES %@",regex

實(shí)際應(yīng)用:對(duì)NSArray進(jìn)行過(guò)濾

NSArray *array = [[NSArray alloc]initWithObjects:@"beijing",@"shanghai",@"guangzou",@"wuhan", nil];  
NSString *string = @"ang";  
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@",string];  
NSLog(@"%@",[array filteredArrayUsingPredicate:pred]);  

實(shí)際應(yīng)用:判斷字符串首字母是否為字母

NSString *regex = @"[A-Za-z]+";  
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];  
  
if ([predicate evaluateWithObject:aString]) {  
}  

實(shí)際應(yīng)用:字符串替換

NSError* error = NULL;  
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"(encoding=\")[^\"]+(\")"  
                                                                           options:0  
                                                                           error:&error];  
NSString* sample = @"<xml encoding=\"abc\"></xml><xml encoding=\"def\"></xml><xml encoding=\"ttt\"></xml>";  
NSLog(@"Start:%@",sample);  
NSString* result = [regex stringByReplacingMatchesInString:sample  
                                                     options:0  
                                                      range:NSMakeRange(0, sample.length)  
                                                     withTemplate:@"$1utf-8$2"];  
NSLog(@"Result:%@", result);  

實(shí)際應(yīng)用:截取字符串

//組裝一個(gè)字符串祷舀,需要把里面的網(wǎng)址解析出來(lái)  
NSString *urlString=@"<meta/><link/><title>1Q84 BOOK1</title></head><body>";  
 
//NSRegularExpression類里面調(diào)用表達(dá)的方法需要傳遞一個(gè)NSError的參數(shù)。下面定義一個(gè)    
NSError *error;  
 
//http+:[^\\s]* 這個(gè)表達(dá)式是檢測(cè)一個(gè)網(wǎng)址的烹笔。(?<=title\>).*(?=</title)截取html文章中的<title></title>中內(nèi)文字的正則表達(dá)式  
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=title\\>).*(?=</title)" options:0 error:&error];  
 
if (regex != nil) {  
   NSTextCheckingResult *firstMatch=[regex firstMatchInString:urlString options:0 range:NSMakeRange(0, [urlString length])];  
     
   if (firstMatch) {  
       NSRange resultRange = [firstMatch rangeAtIndex:0];  
         
       //從urlString當(dāng)中截取數(shù)據(jù)  
       NSString *result=[urlString substringWithRange:resultRange];  
       //輸出結(jié)果  
       NSLog(@"->%@<-",result);  
   }  
     
}  

實(shí)際應(yīng)用:判斷手機(jī)號(hào)碼蔑鹦,電話號(hào)碼函數(shù)

// 正則判斷手機(jī)號(hào)碼地址格式
- (BOOL)isMobileNumber:(NSString *)mobileNum
{
      /**
       * 手機(jī)號(hào)碼
       * 移動(dòng):134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
       * 聯(lián)通:130,131,132,152,155,156,185,186
       * 電信:133,1349,153,180,189
       */
      NSString * MOBILE = @"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";
      /**
       10         * 中國(guó)移動(dòng):China Mobile
       11         * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
       12         */
      NSString * CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$";
      /**
       15         * 中國(guó)聯(lián)通:China Unicom
       16         * 130,131,132,152,155,156,185,186
       17         */
      NSString * CU = @"^1(3[0-2]|5[256]|8[56])\\d{8}$";
      /**
       20         * 中國(guó)電信:China Telecom
       21         * 133,1349,153,180,189
       22         */
      NSString * CT = @"^1((33|53|8[09])[0-9]|349)\\d{7}$";
      /**
       25         * 大陸地區(qū)固話及小靈通
       26         * 區(qū)號(hào):010,020,021,022,023,024,025,027,028,029
       27         * 號(hào)碼:七位或八位
       28         */
     // NSString * PHS = @"^0(10|2[0-5789]|\\d{3})\\d{7,8}$";
   
    NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
    NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
    NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU];
    NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT];
   
   if (([regextestmobile evaluateWithObject:mobileNum] == YES)
   || ([regextestcm evaluateWithObject:mobileNum] == YES)
   || ([regextestct evaluateWithObject:mobileNum] == YES)
   || ([regextestcu evaluateWithObject:mobileNum] == YES))
   {
       if([regextestcm evaluateWithObject:mobileNum] == YES) {
         NSLog(@"China Mobile");
       } else if([regextestct evaluateWithObject:mobileNum] == YES) {
         NSLog(@"China Telecom");
       } else if ([regextestcu evaluateWithObject:mobileNum] == YES) {
         NSLog(@"China Unicom");
       } else {
         NSLog(@"Unknow");
       }
       
       return YES;
   }
   else 
   {
       return NO;
   }
}

實(shí)際應(yīng)用:郵箱驗(yàn)證、電話號(hào)碼驗(yàn)證

//是否是有效的正則表達(dá)式

+(BOOL)isValidateRegularExpression:(NSString *)strDestination byExpression:(NSString *)strExpression

{

  NSPredicate *predicate = [NSPredicatepredicateWithFormat:@"SELF MATCHES %@", strExpression];  

  return [predicate evaluateWithObject:strDestination];

}

//驗(yàn)證email
+(BOOL)isValidateEmail:(NSString *)email {

  NSString *strRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{1,5}";

  BOOL rt = [CommonTools isValidateRegularExpression:email byExpression:strRegex];

  return rt;

}

//驗(yàn)證電話號(hào)碼
+(BOOL)isValidateTelNumber:(NSString *)number {

  NSString *strRegex = @"[0-9]{1,20}";

  BOOL rt = [CommonTools isValidateRegularExpression:number byExpression:strRegex];

  return rt;

}

實(shí)際應(yīng)用:NSDate進(jìn)行篩選

//日期在十天之內(nèi):
NSDate *endDate = [[NSDate date] retain];
NSTimeInterval timeInterval= [endDate timeIntervalSinceReferenceDate];
timeInterval -=3600*24*10;
NSDate *beginDate = [[NSDate dateWithTimeIntervalSinceReferenceDate:timeInterval] retain];
//對(duì)coredata進(jìn)行篩選(假設(shè)有fetchRequest)
NSPredicate *predicate_date =
[NSPredicate predicateWithFormat:@"date >= %@ AND date <= %@", beginDate,endDate];  
[fetchRequest setPredicate:predicate_date];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末箕宙,一起剝皮案震驚了整個(gè)濱河市嚎朽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柬帕,老刑警劉巖哟忍,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異陷寝,居然都是意外死亡锅很,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門凤跑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)爆安,“玉大人,你說(shuō)我怎么就攤上這事仔引∪硬郑” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵咖耘,是天一觀的道長(zhǎng)翘簇。 經(jīng)常有香客問(wèn)我,道長(zhǎng)儿倒,這世上最難降的妖魔是什么版保? 我笑而不...
    開(kāi)封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮夫否,結(jié)果婚禮上彻犁,老公的妹妹穿的比我還像新娘。我一直安慰自己凰慈,他們只是感情好汞幢,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著溉瓶,像睡著了一般急鳄。 火紅的嫁衣襯著肌膚如雪谤民。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天疾宏,我揣著相機(jī)與錄音张足,去河邊找鬼。 笑死坎藐,一個(gè)胖子當(dāng)著我的面吹牛为牍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播岩馍,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼碉咆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蛀恩?” 一聲冷哼從身側(cè)響起疫铜,我...
    開(kāi)封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎双谆,沒(méi)想到半個(gè)月后壳咕,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡顽馋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年谓厘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寸谜。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡竟稳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出熊痴,到底是詐尸還是另有隱情他爸,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布愁拭,位于F島的核電站讲逛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏岭埠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一蔚鸥、第九天 我趴在偏房一處隱蔽的房頂上張望惜论。 院中可真熱鬧,春花似錦止喷、人聲如沸馆类。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)乾巧。三九已至句喜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沟于,已是汗流浹背咳胃。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旷太,地道東北人展懈。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像供璧,于是被迫代替她去往敵國(guó)和親存崖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容