有時我們需要在一大段長文本中過濾出我們需要的字段,或者檢驗該文本是否符合要求(該文本是否是郵箱,鏈接,電話號碼或身份證),這時候就需要用到正則表達式了,iOS中也加入了相關(guān)的類來支持正則表達式的使用。
不會使用正則表達式的讀者可以參考該鏈接 正則表達式30分鐘入門教程 ,閱讀的時候請注意,在Objectiv-C中,"\"是轉(zhuǎn)義字符,書寫正則表達式時應在原式上進行修改,例如要書寫"\b",則在Objectiv-C中應為"\\b",
同理,"\bhello world\b"就應寫為"\\bhello world\\b"
使用iOS SDK中原生的方法
正則表達式
通過以下兩個類我們就能簡單的在iOS開發(fā)中使用正則表達式來過濾或是驗證文本了,本文重點介紹這兩個類
- NSRegularExpression
- NSTextCheckingResult
當然,OC中的另外兩個類
- NSPredicate
- NSString
也提供了正則表達式應用的方法,文章的后面會略微提及一下。
下面我們來介紹這兩個類和他們的基本使用方法,首先我們定義兩段文字,一段是將要被過濾的原文本,另一段是用來過濾他的正則表達式文本
NSString *originalString=@"why not creat a project and try it?http://www.baidu.com"; //將要被處理的string
NSString *regex=@"http+:[^\\s]*"; //正則表達式
準備工作完成,接下來介紹一下NSRegularExpression的一些使用方法
獲取所有符合規(guī)則的字段
NSRegularExpression類常用獲取一段文字中符合規(guī)則的字段;
例如獲取一段文字中全部的郵箱,手機號或是特殊約定的字符串例如微博中的 @用戶名。
這些功能主要通過以下幾個方法來實現(xiàn)
注意,以下方法返回的結(jié)果都是NSTextCheckingResult類型,為方便理解,在注解時我們用“字段”這個詞來表示,但它并不是NSString,該類型在文章的后面會講到。
//枚舉每個符合約定的字段,通過block對其進行操作
- (void)enumerateMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range usingBlock:(void (^)(NSTextCheckingResult * __nullable result, NSMatchingFlags flags, BOOL *stop))block;
//返回一個存有所有符合約定的字段的NSArray
- (NSArray<NSTextCheckingResult *> *)matchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;
//返回符合約定字段的個數(shù)
- (NSUInteger)numberOfMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;
//返回第一個符合約定的字段
- (nullable NSTextCheckingResult *)firstMatchInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;
//返回第一個符合約定的字段在全文中點NSRange
- (NSRange)rangeOfFirstMatchInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;
這里我們以第二個方法為例,演示一下如何獲取所有符合要求的字段
Example:
//原字段
NSString *testString1 = @"clc_cfzxyq@163.com wcowfjwogjwoiejfiow 12321@qq.com 298349845fwe ctftf:iLoveiOS@qq.com";
NSError *error;
//正則表達式,解析郵箱
NSString* regexString = @"\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
//創(chuàng)建一個正則表達式對象,存儲匹配規(guī)則
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString options:0 error:&error];
if (regex != nil) {
//用該方法解析出所有
NSArray* array = [regex matchesInString:testString1 options:NSMatchingReportProgress range:NSMakeRange(0, [testString1 length])];
NSMutableArray* stringArray = [[NSMutableArray alloc] init];
//當解析出的數(shù)組至少有一個對象時,即原文本中存在至少一個符合規(guī)則的字段
if (array.count != 0) {
for (NSTextCheckingResult* result in array) {
//從NSTextCheckingResult類中取出range屬性
NSRange range = result.range;
//從原文本中將字段取出并存入一個NSMutableArray中
[stringArray addObject:[testString1 substringWithRange:range]];
}
}
//打印結(jié)果
NSLog(@"%@",stringArray);
}
這樣我們就從文本中取出了所有的郵箱,運行結(jié)果如下
從上面不難看出,NSTextCheckingResult其實就是一個保存搜索結(jié)果的類,每一個搜索出的結(jié)果都會保存成一個該類的對象,在正則表達式中,只需要用到該類中的range屬性,即檢索結(jié)果在原文中的位置。
替換所有符合規(guī)則的字段
NSRegularExpression類中提供了方法來實現(xiàn)用新的字段來替換原文中符合規(guī)則的字段。大致有以下幾種
//用新字段替換原文本中的對應字段,并返回操作后的NSString
- (NSString *)stringByReplacingMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range withTemplate:(NSString *)templ;
//用新字段替換原文本中的對應字段,并返回操作次數(shù)(替換字段的個數(shù))
- (NSUInteger)replaceMatchesInString:(NSMutableString *)string options:(NSMatchingOptions)options range:(NSRange)range withTemplate:(NSString *)templ;
用第一個方法舉例說明
Example:
//需要進行替換的NSString,轉(zhuǎn)換成方法需要的NSMutableString
NSString *testString1 = @"clc_cfzxyq@163.com wcowfjwogjwoiejfiow 12321@qq.com 298349845fwe ctftf:iLoveiOS@qq.com";
NSMutableString* testString2 = [NSMutableString stringWithString:testString1];
NSError *error;
//正則表達式
NSString* regexString = @"\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString options:0 error:&error];
if (regex != nil) {
//使用方法進行文本替換
NSString* resultString = [regex stringByReplacingMatchesInString:testString2 options:NSMatchingReportProgress range:NSMakeRange(0, [testString2 length]) withTemplate:@"uuuuuuuuuuu"];
//打印驗證結(jié)果
NSLog(@"%@",resultString);
}
這里我們將文本中所有的郵箱都替換成了uuuuuuuuuuu
打印如下
判斷字符串是否符合表達式(NSPredicate)
這里我們用到NSPredicate類的方法
NSString *testString = @"clc_cfzxyq@163.com";
NSString *regex = @"\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
//注意這里的格式 @"SELF MATCHES %@", regex
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
//判斷
BOOL isValid = [predicate evaluateWithObject: testString];
if (isValid) {
NSLog(@"YES");//是則打印YES
}
通過該方法可以檢測文本是否符合某些特定要求(純數(shù)字,純英文,電話號碼,郵箱,身份證等)
這里給出一篇文章,里面有常用的正則表達式示例一個正則表達式測試(只可輸入中文、字母和數(shù)字)
NSString中使用正則表達式
NSString中使用正則表達式的方法比較輕量級,大致如下
//注意,這些方法里options的值取NSRegularExpressionSearch
- (NSRange)rangeOfString:(NSString *)searchString options:(NSStringCompareOptions)mask;
- (NSRange)rangeOfString:(NSString *)searchString options:(NSStringCompareOptions)mask range:(NSRange)searchRange;
- (NSRange)rangeOfString:(NSString *)searchString options:(NSStringCompareOptions)mask range:(NSRange)searchRange locale:(nullable NSLocale *)locale NS_AVAILABLE(10_5, 2_0);
這些方法的用法就像方法名一樣耿直,大家都是聰明的程序猿,這里就不多做講解了。