使用NSRegularExpression自動識別電話號碼

最近項目中碰到了這樣一個需求,需要在一段文字中識別出手機號,并加上特殊顏色,和點擊事件。下面說下我的思路,拋磚引玉。(如果你有更好的想法,不妨交流下)

前提是基于TTTAttributedLabel實現的。因為TTTAttributedLabel已經做了添加鏈接,我們目的是找出應該在哪里加鏈接,關于怎么加上,以及點擊鏈接的代理事件不是本文重點。工欲善其事,必先利其器嗎。(以下內容僅以國內固話和手機號為例,不涉及國外電話)

思路

主要分為兩步,

  1. 先粗略找出字符串中可能為固話和手機號的子字符串及其在該字符串中的位置range。
    什么是可能為電話號碼的字符串,比如18000000000(連續11位數字),010-66666666(3位區號-8位號碼)還有(3-7,4-8,4-7)以及區號和號碼之間不用“-”的,這些都是有可能為電話號碼的。
    用正則表達式表示就是

     #define PHONEREGULAR @"\\d{3,4}[- ]?\\d{7,8}"http://匹配10到12位連續數字,或者帶連字符/空格的固話號,空格和連字符可以省略。
    

關于正則表達式這里有篇30分鐘入門教程
核心代碼實現

    self.ddLabel.text = tempStr;

    NSRange stringRange = NSMakeRange(0, tempStr.length);
    //正則匹配
    NSError *error;
    NSRegularExpression *regexps = [NSRegularExpression regularExpressionWithPattern:PHONEREGULAR options:0 error:&error];
    if (!error && regexps != nil) {
        [regexps enumerateMatchesInString:[tempStr string] options:0 range:stringRange usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) {
        
            //可能為電話號碼的字符串及其所在位置
            NSString *actionString = [NSString stringWithFormat:@"%@",[self.ddLabel.text substringWithRange:result.range]];
            NSRange phoneRange = result.range;
            //這里需要判斷是否是電話號碼,并添加鏈接
            if ([DDUtil isMobilePhoneOrtelePhone:actionString]) {
              [self.ddLabel addLinkToPhoneNumber:actionString withRange:result.range];
            
            }
        }];
    }
  1. 當然只判斷這些肯定是不夠的,像這種20899999999,很明顯不是電話號,上面也匹配了。我們第二步就是篩選是手機號的并加上鏈接。這里我直接用了我們項目里的工具類,這個代碼網上一搜一堆,不再介紹。
    主要代碼實現
 *  // 驗證是固話或者手機號
 *
 *  @param mobileNum 手機號
 *
 *  @return 是否
 */
+ (BOOL)isMobilePhoneOrtelePhone:(NSString *)mobileNum {
    if (mobileNum==nil || mobileNum.length ==0) {
        return NO;
    }
    /**
     * 手機號碼
     * 移動:134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
     * 聯通:130,131,132,152,155,156,185,186
     * 電信:133,1349,153,180,189
     */
    NSString * MOBILE = @"^((13)|(14)|(15)|(17)|(18))\\d{9}$";// @"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";
    /**
     10         * 中國移動: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         * 中國聯通: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         * 中國電信:China Telecom
     21         * 133,1349,153,180,189
     22         */
    NSString * CT = @"^1((33|53|8[09])[0-9]|349)\\d{7}$";
    /**
     25         * 大陸地區固話及小靈通
     26         * 區號:010,020,021,022,023,024,025,027,028,029
     27         * 號碼:七位或八位
     28         */
    NSString * PHS = @"^((0\\d{2,3}-?)\\d{7,8}(-\\d{2,5})?)$";// @"^0(10|2[0-5789]-|\\d{3})\\d{7,8}$";
    
    NSPredicate *regextestPHS = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", PHS];
    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)
        || ([regextestPHS evaluateWithObject:mobileNum]==YES)) {
        return YES;
    }
    else{
        return NO;
    }
}

效果圖

1.png

源代碼

源碼

注意

沒有做沒加區號的號碼匹配,其實我們項目里面只做手機號就行了。感興趣的可以自己加。當然對這些特殊的110,120,也不會支持。這個在我們項目里根本是錄不進去的,因為做了嚴格的輸入限制,只能輸11位手機號。作為展示,肯定不會有110,120,這種無聊的數據的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,176評論 4 61
  • 參考文章 正則表達式30分鐘入門教程 學習之前 學習之前,先安裝一個Mac上用的軟件,來測試你的正則表達式是否正確...
    劉大帥閱讀 3,767評論 2 36
  • 前幾天發現一個公共號,有一百多篇文章,每一篇都是以作者自己敘述身邊小故事的方式來寫的,但是卻絲毫不會讓人覺得反感。...
    小明媳婦06閱讀 345評論 0 0
  • 記得小學一年級的時候,真正意義上關注你是運動會上你上臺領獎,那時候覺得怎么會有長得這么高的人,后來彼此慢慢熟絡起來...
    南馭閱讀 353評論 6 6
  • 堅持,說出來如此容易的詞,為什么實際做的時候卻那么的難呢? 實際上堅持不了太長時間只是你太傲嬌了而已啦。 曾經的某...
    大司馬與少司命閱讀 417評論 0 0