最近項目需要本地檢測手機號碼正確性黎茎,于是用了一段代碼,但是后來發(fā)現(xiàn)這個代碼塊已經過時了续徽。在網上簡單找了下,發(fā)現(xiàn)沒有最新的一個公開代碼亲澡,可能很多人都是用的下面正則方法來檢測手機號碼钦扭,那你們該更新代碼了。眾所周知床绪,三大運營商已經增加了不少手機號碼字段土全,還用之前的代碼就會流失部分用戶了捎琐。(只討論國內壞境)
于是我在網上查了些數據,在之前的代碼基礎上改了下裹匙,方便適用于現(xiàn)在的環(huán)境。
所用方法依然還是正則表達式末秃,正則表達式主要就是用一個公式來匹配字符串是否具備某類規(guī)則。我們這里的思路和之前也是一樣,只是對之前方法的一個補充與解析留搔。新的方法只匹配了手機號碼字段前三位译红,有些朋友可能還不太懂這個方法,為了方便大家使用铃将,在最后會為大家簡單拆分該方法项鬼,相信大家很快就會靈活應用了。
舊的正則表達式代碼:
- (BOOL)isMobileNumber:(NSString *)mobileNum
{
/**
* 手機號碼
* 移動:134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,184,187,188
* 聯(lián)通:130,131,132,145,152,155,156,1709,171,176,185,186
* 電信:133,134,153,1700,177,180,181,189
*/
NSString * MOBILE = @"^1(3[0-9]|4[57]|5[0-35-9]|7[01678]|8[0-9])\\d{8}$";
/**
* 中國移動:China Mobile
* 134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,184,187,188
*/
NSString * CM = @"^1(3[4-9]|4[7]|5[0-27-9]|7[0]|7[8]|8[2-478])\\d{8}$";
/**
* 中國聯(lián)通:China Unicom
* 130,131,132,145,152,155,156,1709,171,176,185,186
*/
NSString * CU = @"^1(3[0-2]|4[5]|5[56]|709|7[1]|7[6]|8[56])\\d{8}$";
/**
* 中國電信:China Telecom
* 133,134,153,1700,177,180,181,189
*/
NSString * CT = @"^1(3[34]|53|77|700|8[019])\\d{8}$";
/**
* 大陸地區(qū)固話及小靈通
* 區(qū)號:010,020,021,022,023,024,025,027,028,029
* 號碼:七位或八位
*/
// 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))
{
return YES;
}
else
{
return NO;
}
}
新版正則表達式代碼:
+ (BOOL)isMobileNumber:(NSString *)mobileNum
{
if (mobileNum.length != 11)
{
return NO;
}
/**
* 手機號碼:
* 13[0-9], 14[5,7, 9], 15[0, 1, 2, 3, 5, 6, 7, 8, 9], 17[0-9], 18[0-9]
* 移動號段: 134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,184,187,188
* 聯(lián)通號段: 130,131,132,145,155,156,170,171,175,176,185,186
* 電信號段: 133,149,153,170,173,177,180,181,189
*/
NSString *MOBILE = @"^1(3[0-9]|4[579]|5[0-35-9]|7[0-9]|8[0-9])\\d{8}$";
/**
* 中國移動:China Mobile
* 134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,184,187,188
*/
NSString *CM = @"^1(3[4-9]|4[7]|5[0-27-9]|7[08]|8[2-478])\\d{8}$";
/**
* 中國聯(lián)通:China Unicom
* 130,131,132,145,155,156,170,171,175,176,185,186
*/
NSString *CU = @"^1(3[0-2]|4[5]|5[56]|7[0156]|8[56])\\d{8}$";
/**
* 中國電信:China Telecom
* 133,149,153,170,173,177,180,181,189
*/
NSString *CT = @"^1(3[3]|4[9]|53|7[037]|8[019])\\d{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))
{
return YES;
}
else
{
return NO;
}
}
下面我們簡單拆分上面方法劲阎,來應對不同的需求
如果只是簡單匹配是否是 手機號碼绘盟,并不需要上面那么多行代碼,可以簡單寫成這樣:
NSString *MOBILE = @"^1(3[0-9]|4[57]|5[0-35-9]|7[0135678]|8[0-9])\\d{8}$";
NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
return [regextestmobile evaluateWithObject:mobileNum];
如果你需要匹配是否是 移動/聯(lián)通/電信 手機號悯仙。
判斷移動手機號就是這樣:
+ (BOOL)isChinaMobile:(NSString *)phoneNum
{
NSString *CM = @"^1(3[4-9]|4[7]|5[0-27-9]|7[08]|8[2-478])\\d{8}$";
NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
return [regextestcm evaluateWithObject:phoneNum];
}
相信細心的朋友龄毡,應該已經明白了。判斷聯(lián)通手機號锡垄,只要把我們的正則字符串改成上面判斷聯(lián)通手機號的字符串就可以了沦零。判斷哪種就改變正則表達式就可以了
ok,在這個基礎上货岭,我們還可以組合來判斷具體是哪個運營商的手機號路操,代碼如下:
+ (NSString *)getPhoneNumType:(NSString *)phoneNum
{
return [self isChinaMobile:phoneNum]? @"中國移動": ([self isChinaUnicom:phoneNum]? @"中國聯(lián)通":([self isChinaTelecom:phoneNum]? @"中國電信": @"未知"));
}
主要方法都已公布,至于swift或者其他語言代碼塊就不一一放上來了千贯,真讓我都寫屯仗,我也不一定都會。丈牢。祭钉。哈哈哈,核心正則表達式己沛,都是可以用的慌核,拿著代入進去就ok了。
最后如果發(fā)現(xiàn)問題申尼,請告訴我垮卓,方便我及時進行修改。(感謝 @聯(lián)通企業(yè)平臺-專家客戶 提供的數據)
2016-08-15 修改更新手機匹配字段师幕,包括171粟按,170等虛擬字段
因為虛擬號碼增加太快诬滩,對于170號段我這里已經放開了,并沒有精確到是哪個運營商灭将。只要170號段的號碼都能過疼鸟。
大家如果不是要求那么精準的話,可以使用 流刃若火泣 的正則表達式: ^1(3|4|5|7|8)[0-9]\d{8}$
2017-12-04 修改17x等虛擬號段
對于17x號段徹底放開庙曙,并沒有精確到是哪個運營商空镜。只要17開頭的號段的號碼都能過。
在網上看到個網址捌朴,據說每月都更新吴攒,可以自測一下。如果需要精準號碼是何運營商砂蔽,可以根據此網址來修改對應正則表達式
http://www.xeasy.net/mobile/register.php
感謝每一位評論者的意見與建議洼怔,thanks