開篇
通過(guò)簡(jiǎn)書iOS客戶端登錄,我們會(huì)看到請(qǐng)輸入手機(jī)號(hào)或者郵箱登錄,但是我們隨機(jī)輸入1234567的時(shí)候尸红,便會(huì)彈出手機(jī)格式不正確,同樣也會(huì)識(shí)別我們的郵箱格式刹泄,那么我們?cè)陧?xiàng)目中怎么實(shí)現(xiàn)這種判斷呢外里?
這就是我們今天要說(shuō)的正則表達(dá)式。
正則表達(dá)式的介紹
正則表達(dá)式有多種使用方法特石,根據(jù)我們的需要盅蝗,我們是要判斷輸入是否合法,還是查找指定的內(nèi)容姆蘸,還是捕獲多個(gè)輸入的內(nèi)容墩莫,可以選用不同的方法芙委,今天我們主要說(shuō)一下,判斷輸入是否合法狂秦,用謂詞的方式來(lái)創(chuàng)建正則表達(dá)式灌侣,以后如果有用到的,再寫一篇吧裂问。
謂詞(NSPredicate)
NSPredicate是什么意思呢侧啼。NSPredicate即謂詞邏輯。和數(shù)據(jù)庫(kù)的SQL語(yǔ)句具有相似性堪簿,都是從數(shù)據(jù)堆中根據(jù)條件進(jìn)行篩選痊乾。
謂詞,指定過(guò)濾器的條件椭更,將符合條件的對(duì)象保留下來(lái) 符喝,一般用謂詞過(guò)濾數(shù)組中指定的元素 ,定義謂詞對(duì)象甜孤,謂詞對(duì)象中包含了過(guò)濾元素协饲,使用謂詞條件過(guò)濾之后得到我們想要的結(jié)果〗纱ǎ總得來(lái)說(shuō)呢茉稠,Cocoa提供了一個(gè)類NSPredicate類,該類主要用于指定過(guò)濾器的條件把夸,該對(duì)象可以準(zhǔn)確的描述所需條件而线,對(duì)每個(gè)對(duì)象通過(guò)謂詞進(jìn)行篩選,判斷是否與條件相匹配恋日。謂詞表示計(jì)算真值或假值的函數(shù)膀篮。
下面進(jìn)行代碼舉例,首先我們創(chuàng)建一個(gè)名為Student的類岂膳,然后給他設(shè)定id誓竿,name,height谈截。之后我們引入這個(gè)類給他賦值筷屡,代碼如下:
NSMutableArray *array=[NSMutableArray arrayWithCapacity: 5];
Student *student1=[[Student alloc] init];
[student1 setPid: 1];
[student1 setName: @"xiaoming"];
[student1 setHeight: 168];
[array addObject: student1];
Student *student2=[[Student alloc] init];
[student2 setPid: 2];
[student2 setName: @"dahuang"];
[student2 setHeight: 178];
[array addObject: student2];
Student *student3=[[Student alloc] init];
[student3 setPid: 3];
[student3 setName: @"erhuang"];
[student3 setHeight: 188];
[array addObject: student3];
在上述的代碼中,我們創(chuàng)建了一個(gè)可變數(shù)組簸喂,和三個(gè)小學(xué)生(-_-,不要吐槽我給他們的命名毙死,懶得想..).
下面我們就要?jiǎng)?chuàng)建我們的謂詞了,我們想要篩選出一個(gè)id 大于1 喻鳄,且升高小于180的小學(xué)生來(lái)扼倘,應(yīng)該怎么做呢。
NSPredicate *pre = [NSPredicate predicateWithFormat:
@" pid>1 and height<188.0"];
int i=0;
for(i=0;i<[array count];i++){
Student *stu=[array objectAtIndex: i];
//遍歷數(shù)組除呵,輸出符合謂詞條件的Student 的name再菊。
if ([pre evaluateWithObject: stu]) {
NSLog(@"11--%@",[stu name]);
}
}
謂詞還可以幫我們做出一些列的篩選爪喘,如下:
//快速篩選數(shù)組內(nèi)容 以及占位符的使用
NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"pid>%d",1];
NSMutableArray *arrayPre2=[array filteredArrayUsingPredicate: pre2];
NSLog(@"%@",[[arrayPre2 objectAtIndex: 0] name]);
字符串的處理
//name以x開頭的
NSPredicate *predicate3 = [NSPredicate predicateWithFormat:@"name BEGINSWITH 'x'"];
//name以g結(jié)尾的
NSPredicate *predicate4 = [NSPredicate predicateWithFormat:@"name ENDSWITH 'g'"];
//name中包含字符a的
NSPredicate *predicate5 = [NSPredicate predicateWithFormat:@"name CONTAINS 'a'"];
//like 匹配任意多個(gè)字符
//name中只要有r字符就滿足條件
NSPredicate *predicate6 = [NSPredicate predicateWithFormat:@"name like '*r*'"];
//?代表一個(gè)字符,下面的查詢條件是:name中第二個(gè)字符是r的
NSPredicate *predicate7 = [NSPredicate predicateWithFormat:@"name like '*?r*'"];
謂詞的使用就先到這里袄简,是不是和數(shù)據(jù)庫(kù)使用感覺(jué)差不多呢腥放,下面說(shuō)說(shuō)正題的時(shí)候來(lái)了,我們要怎么進(jìn)行把謂詞和正則表達(dá)式結(jié)合進(jìn)行相應(yīng)的判斷呢绿语。
利用正則表達(dá)式實(shí)現(xiàn)判斷
首先我們建立一個(gè)UI秃症,包含一個(gè)UITextField輸入框和一個(gè)提交按鈕,當(dāng)我們點(diǎn)擊按鈕的時(shí)候?qū)ξ覀兲峤坏臄?shù)據(jù)進(jìn)行判斷吕粹。
我們創(chuàng)建一個(gè)類种柑,寫出對(duì)手機(jī)號(hào)和郵箱進(jìn)行判斷的方法
+ (BOOL)GS_isMobileNumber:(NSString *)mobileNum;
+ (BOOL)GS_isEmailQualified:(NSString *)emailStr;
然后實(shí)現(xiàn)檢測(cè)的方法
+ (BOOL)GS_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}$";
/**
* 中國(guó)移動(dòng):China Mobile
* 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
*/
// NSString * CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$"; // China Mobile phoneNum
/**
* 中國(guó)聯(lián)通:China Unicom
* 130,131,132,152,155,156,185,186
*/
// NSString * CU = @"^1(3[0-2]|5[256]|8[56])\\d{8}$"; // China Unicom phoneNum
/**
* 中國(guó)電信:China Telecom
* 133,1349,153,180,189
*/
// NSString * CT = @"^1((33|53|8[09])[0-9]|349)\\d{7}$"; // China Telecom phoneNum
/**
* The following 4 predicate can tell which carrier the number is from.
*/
// 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];
//Only Check if the string is a valid telephone number, ignoring the carrier info.
NSString *isMobileRegex = @"^(((13[0-9]{1})|(15[0-9]{1})|(17[0-9]{1})|(18[0,5-9]{1}))+\\d{8})$";
// NSString *isMobileRegex = @"^((\\+86)|(\\(\\+86\\)))?(((13[0-9]{1})|(15[0-9]{1})|(17[0-9]{1})|(18[0,5-9]{1}))+\\d{8})$";
NSPredicate *mobileRegex = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", isMobileRegex];
if (([mobileRegex evaluateWithObject: mobileNum] == YES))
{
return YES;
}else{
return NO;
}
}
//檢測(cè)是否為郵箱
+ (BOOL)GS_isEmailQualified:(NSString *)emailStr
{
NSString *pattern = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:pattern options:0 error:nil];
NSArray *results = [regex matchesInString:emailStr options:0 range:NSMakeRange(0, emailStr.length)];
return results.count > 0;
}
然后我們調(diào)用創(chuàng)建的方法,去檢測(cè)是否為手機(jī)號(hào)
if ([GSRegularExpression GS_isMobileNumber:_textfiled.text]) {
NSLog(@"輸入的是正常的手機(jī)號(hào)碼");
}else{
NSLog(@"輸入的不是正常的手機(jī)號(hào)碼");
}
根據(jù)打印結(jié)果匹耕,顯示我們是正確的這樣聚请,我們就實(shí)現(xiàn)了正則表達(dá)式對(duì)手機(jī)號(hào)和郵箱的判定(郵箱的這是這種調(diào)用方式)。
后記
正則表達(dá)式去判斷一些結(jié)果稳其,是比較常用的驶赏,比如,身份證既鞠,車牌煤傍,機(jī)型,IP地址嘱蛋,輸入是否為全數(shù)字等蚯姆。利用他我們可以實(shí)現(xiàn)一些看來(lái)比較復(fù)雜的效果,現(xiàn)在我們已經(jīng)實(shí)現(xiàn)了簡(jiǎn)書的登錄對(duì)手機(jī)號(hào)和郵箱識(shí)別的功能洒敏,希望對(duì)大家有所幫助龄恋。文中有不對(duì)的地方,歡迎大家積極指出凶伙。
補(bǔ)充
補(bǔ)充1:
例如我們給定一個(gè)用來(lái)判斷密碼的正則
+(BOOL)judgePassWordLegal:(NSString *)pass{
BOOL result ;
// 判斷長(zhǎng)度大于8位后再接著判斷是否同時(shí)包含數(shù)字和字符
NSString * regex = @"^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
result = [pred evaluateWithObject:pass];
NSLog(@"%hhd",result);
return result;
}
對(duì)以上正則我們來(lái)怎么理解他呢郭毕? 首先開頭標(biāo)記 "^" 結(jié)尾標(biāo)記 "$" ,[0-9A-Za-z]{6,20}表示內(nèi)容包含數(shù)字和字母并且限制了他的位數(shù),(?![0-9]+$)這個(gè)形式 正向否定預(yù)查镊靴,具體的格式意義铣卡,這里放上一個(gè)網(wǎng)上的鏈接就不一一寫了,正則表達(dá)式的用法 偏竟。
補(bǔ)充2:
關(guān)于評(píng)論里面的登錄的問(wèn)題這里做一下補(bǔ)充:基本流程僅作參考,有不當(dāng)?shù)臍g迎指出敞峭。
已授權(quán)過(guò)—— 授權(quán)之后踊谋,請(qǐng)求接口——>已綁定過(guò)——>返回登錄信息
未授權(quán)—— 授權(quán)之后,請(qǐng)求接口——>沒(méi)有綁定過(guò)——>(手機(jī)號(hào)已經(jīng)注冊(cè))——>(openid和userid或者手機(jī)號(hào)綁定旋讹,然后返回登錄信息)
未授權(quán)——> 授權(quán)之后殖蚕,請(qǐng)求接口——>沒(méi)有綁定過(guò)——>(沒(méi)注冊(cè)過(guò)的)——>創(chuàng)建賬號(hào)轿衔,綁定id——>返回登錄信息