最近項(xiàng)目中碰到了這樣一個(gè)需求,需要在一段文字中識別出手機(jī)號,并加上特殊顏色呐赡,和點(diǎn)擊事件。下面說下我的思路骏融,拋磚引玉链嘀。(如果你有更好的想法,不妨交流下)
前提是基于TTTAttributedLabel實(shí)現(xiàn)的档玻。因?yàn)門TTAttributedLabel已經(jīng)做了添加鏈接怀泊,我們目的是找出應(yīng)該在哪里加鏈接,關(guān)于怎么加上误趴,以及點(diǎn)擊鏈接的代理事件不是本文重點(diǎn)霹琼。工欲善其事,必先利其器嗎凉当。(以下內(nèi)容僅以國內(nèi)固話和手機(jī)號為例碧囊,不涉及國外電話)
思路
主要分為兩步,
-
先粗略找出字符串中可能為固話和手機(jī)號的子字符串及其在該字符串中的位置range纤怒。
什么是可能為電話號碼的字符串糯而,比如18000000000(連續(xù)11位數(shù)字),010-66666666(3位區(qū)號-8位號碼)還有(3-7泊窘,4-8熄驼,4-7)以及區(qū)號和號碼之間不用“-”的像寒,這些都是有可能為電話號碼的。
用正則表達(dá)式表示就是#define PHONEREGULAR @"\\d{3,4}[- ]?\\d{7,8}"http://匹配10到12位連續(xù)數(shù)字瓜贾,或者帶連字符/空格的固話號诺祸,空格和連字符可以省略。
關(guān)于正則表達(dá)式這里有篇30分鐘入門教程
核心代碼實(shí)現(xiàn)
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];
}
}];
}
- 當(dāng)然只判斷這些肯定是不夠的筷笨,像這種20899999999,很明顯不是電話號龟劲,上面也匹配了胃夏。我們第二步就是篩選是手機(jī)號的并加上鏈接。這里我直接用了我們項(xiàng)目里的工具類昌跌,這個(gè)代碼網(wǎng)上一搜一堆仰禀,不再介紹。
主要代碼實(shí)現(xiàn)
* // 驗(yàn)證是固話或者手機(jī)號
*
* @param mobileNum 手機(jī)號
*
* @return 是否
*/
+ (BOOL)isMobilePhoneOrtelePhone:(NSString *)mobileNum {
if (mobileNum==nil || mobileNum.length ==0) {
return NO;
}
/**
* 手機(jī)號碼
* 移動: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 = @"^((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 * 中國聯(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 * 中國電信: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ū)號: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;
}
}
效果圖
源代碼
注意
沒有做沒加區(qū)號的號碼匹配蚕愤,其實(shí)我們項(xiàng)目里面只做手機(jī)號就行了答恶。感興趣的可以自己加。當(dāng)然對這些特殊的110萍诱,120悬嗓,也不會支持。這個(gè)在我們項(xiàng)目里根本是錄不進(jìn)去的裕坊,因?yàn)樽隽藝?yán)格的輸入限制包竹,只能輸11位手機(jī)號。作為展示碍庵,肯定不會有110,120悟狱,這種無聊的數(shù)據(jù)的静浴。