本文主要紹介在OC的以下3個類中使用正則表達(dá)式:?
1. NSString帶有options選項的一般都支持正則表達(dá)式?
特點: 只匹配第一個, 可指定是否區(qū)分大小寫. 可替換字符串.?
2. NSRegularExpression類?
能匹配多個結(jié)果, 替換內(nèi)容等, 從名字就可以看出來 ,它是OC中實現(xiàn)正則表達(dá)式功能最全面的類.?
3. NSPredicate類的matches命令?
重在檢索數(shù)據(jù)
PS: 以上3個類用的都是ICU(International Components for Unicode)正則引擎(好像OC都是), 3個類就正則表達(dá)式而言,NSRegularExpression最全面,其它2個也有不同程度的實現(xiàn),這么多類,到底用哪個好呢?
NSString 簡單的字符串查找、替換;
NSRegularExpression 復(fù)雜的文本匹配、替換;
NSPredicate 復(fù)雜文本、對象等數(shù)據(jù)檢索, 有點像一個支持正則的SQL語句.
// ----------- 1. NSString帶有options選項的一般都支持正則表達(dá)式? ------------
//a. 是否以某字符串開頭, 不區(qū)分大小寫. 以當(dāng)前語言環(huán)境
NSLog(@"%@",[NSLocale currentLocale].localeIdentifier);? //測試時結(jié)果為"zh_CN";
NSString *str2 = @"Yxwlzs大@126.com123";
NSRange range1 = [str2 rangeOfString:@"[a-z]" //以英文字母開頭
?? ? ? ? ? ? ? ? ? ? ? ? ? ? options:NSRegularExpressionSearch | NSAnchoredSearch | NSCaseInsensitiveSearch
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? range:NSMakeRange(0, str2.length)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? locale:[NSLocale currentLocale]];
//NSRegularExpressionSearch 只能和 NSAnchoredSearch(以某字符串開頭)/NSCaseInsensitiveSearch(忽略大小寫)選項配合使用,其它選項無效;
//如果不使用NSRegularExpressionSearch時, NSAnchoredSearch可配合 NSBackwardsSearch
//locale是NSLocale對象, 代理語言環(huán)境, NSString是處理字符串的, 區(qū)分語言環(huán)境是可以理解的.
//b. 使用英語環(huán)境,結(jié)果沒有發(fā)現(xiàn)有什么不同.
NSRange range2 = [str2 rangeOfString:@"[a-z]" //以英文字母開頭
?? ? ? ? ? ? ? ? ? ? ? ? ? ? options:NSRegularExpressionSearch | NSAnchoredSearch | NSCaseInsensitiveSearch
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? range:NSMakeRange(0, str2.length)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? locale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
NSLog(@"\n%@\n%@",NSStringFromRange(range1),NSStringFromRange(range2));
/* 結(jié)果:
?{0, 1}
?{0, 1}
?*/
// 斷言/檢索/替換
bool exist = range2.location != NSNotFound;
if (exist) {
? ? NSString *subString = [str2 substringWithRange:range2];
? ? NSString *newString = [str2 stringByReplacingCharactersInRange:range2 withString:@"_ReplaceString_"];
? ? NSLog(@"\n斷言: %@, \n檢索: %@, \n替換結(jié)果: %@", exist?@"true":@"false", subString, newString);
}
/*結(jié)果:
?斷言: true,
?檢索: Y,
?替換結(jié)果: _ReplaceString_xwlzs大@126.com123
?*/
在NSRegularExpression對應(yīng)的頭文件中可見以有以下方法:
// *************** 匹配方法 ***************
//迭代每次計算過程
- (void)enumerateMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range usingBlock:(void (^)(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop))block;
//返回匹配數(shù)據(jù)
- (NSArray *)matchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;
//匹配總數(shù)
- (NSUInteger)numberOfMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;
//匹配第一個,不過返回的是 NSTextCheckingResult 類似
//NSTextCheckingResult類: 能檢測到匹配類型, 如URL/手機(jī)號等
- (NSTextCheckingResult *)firstMatchInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;
//匹配第一個
- (NSRange)rangeOfFirstMatchInString:(NSString *)string optios:(NSMatchingOptions)options range:(NSRange)range;
// *************** 替換方法 ***************
// 返回替換后的新字符串, 源字符串不變
- (NSString *)stringByReplacingMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range withTemplate:(NSString *)templ;
// 直接在源字符串里替換
- (NSUInteger)replaceMatchesInString:(NSMutableString *)string options:(NSMatchingOptions)options range:(NSRange)range withTemplate:(NSString *)templ;
// 在 string 中查找由 result + offset 指定的字符串, 返回 template 指定的字符串(比如$0-9等);
- (NSString *)replacementStringForResult:(NSTextCheckingResult *)result inString:(NSString *)string offset:(NSInteger)offset template:(NSString *)templ;
// *************** 其它 ***************
// 正則表達(dá)式字符串, 包括一些特殊字符.
+ (NSString *)escapedTemplateForString:(NSString *)string;
//options參數(shù):
typedef NS_OPTIONS(NSUInteger, NSMatchingOptions) {
? ? NSMatchingReportProgress? ? ? ? =1 << 0, //找到最長的匹配字符串后調(diào)用block回調(diào)
? ? NSMatchingReportCompletion? ? ? =1 << 1, //找到任何一個匹配串后都回調(diào)一次block
? ? NSMatchingAnchored? ? ? ? ? ? ? =1 << 2, //從匹配范圍的開始處進(jìn)行匹配
? ? NSMatchingWithTransparentBounds? =1 << 3, //允許匹配的范圍超出設(shè)置的范圍
? ? NSMatchingWithoutAnchoringBounds =1 << 4? //禁止^和$自動匹配行還是和結(jié)束
};
//enumerateMatchesInString 的 block 回調(diào)中的 flags 枚舉對應(yīng)如下:
typedef NS_OPTIONS(NSUInteger, NSMatchingFlags) {
? ? NSMatchingProgress? ? ? ? ? ? ? =1 << 0, //匹配到最長串是被設(shè)置
? ? NSMatchingCompleted? ? ? ? ? ? ? =1 << 1, //全部分配完成后被設(shè)置
? ? NSMatchingHitEnd? ? ? ? ? ? ? ? =1 << 2, //匹配到設(shè)置范圍的末尾時被設(shè)置
? ? NSMatchingRequiredEnd? ? ? ? ? ? =1 << 3, //當(dāng)前匹配到的字符串在匹配范圍的末尾時被設(shè)置
? ? NSMatchingInternalError? ? ? ? ? =1 << 4? //由于錯誤導(dǎo)致的匹配失敗時被設(shè)置
};
例子: 查找數(shù)組中包含單詞最多的元素,單詞以空格分隔.
//查找數(shù)組中包含單詞最多的元素,單詞以空格分隔.
NSArray *words = @[@"a b cc",
?? ? ? ? ? ? ? ? ? @" a? ? b ccdd d ",
?? ? ? ? ? ? ? ? ? @"test"];
__block int maxNum = 0;
__block int index = 0;
[words enumerateObjectsUsingBlock:^(NSString* obj, NSUInteger idx, BOOL *stop) {
? ? NSRegularExpression *regx = [NSRegularExpression
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? regularExpressionWithPattern:@"\\s*\\w+\\s*"
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? options:NSRegularExpressionCaseInsensitive
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? error:nil];
? ? NSArray *result = [regx matchesInString:obj options:0 range:NSMakeRange(0, obj.length)];
? ? if (maxNum < result.count) {
? ? ? ? maxNum = (int)result.count;
? ? ? ? index = (int)idx;
? ? }
}];
NSLog(@"maxNum = %d, words[%d] = %@", maxNum,index,words[index]);
/*結(jié)果:
?maxNum = 4, words[1] =? a? ? b ccdd d
?*/
NSString *email = @"Yxwl_zsab1@126.com";NSString *regex = @"\\w+@\\w+\\.[a-zA-Z0-9]{2,4}";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];BOOL isValid = [predicate evaluateWithObject:email];
NSPredicate 一般只返回一個BOOL值, 表示條件是否成功(如正則表達(dá)式是否匹配).