iOS中3种正则表达式的使用与比较

时间:2022-11-11 15:25:36

之前我在博文中介绍过iOS中自带正则表达式的使用( 传送门),后来我发现其实iOS中有三种方式来实现正则表达式的匹配。现在将他们都记录在这里: 
1.利用NSPredicate(谓词)匹配 
例如匹配有效邮箱: 

?
1
2
3
4
NSString *email = @“nijino_saki@163.com”; 
NSString *regex = @ "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
NSPredicate *predicate = [NSPredicate predicateWithFormat:@ "SELF MATCHES %@" , regex]; 
BOOL  isValid = [predicate evaluateWithObject:email];


谓词匹配比较灵活,但是需要有谓词的相关知识。 

2.利用rangeOfString:option:直接查找 

?
1
2
3
4
5
6
7
NSString *searchText = @ "// Do any additional setup after loading the view, typically from a nib."
 
NSRange range = [searchText rangeOfString:@ "(?:[^,])*\\."  options:NSRegularExpressionSearch]; 
 
if  (range.location != NSNotFound) { 
     NSLog(@ "%@" , [searchText substringWithRange:range]); 
}


options中设定NSRegularExpressionSearch就是表示利用正则表达式匹配,会返回第一个匹配结果的位置。 

3.使用正则表达式类 


?
1
2
3
4
5
6
7
NSString *searchText = @ "// Do any additional setup after loading the view, typically from a nib." ;    
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@ "(?:[^,])*\\."  options:NSRegularExpressionCaseInsensitive error:&error];
NSTextCheckingResult *result = [regex firstMatchInString:searchText options:0 range:NSMakeRange(0, [searchText length])];
if  (result) {
     NSLog(@ "%@\n" , [searchText substringWithRange:result.range]);
}


使用系统的正则表达式类(NSRegularExpression)会返回匹配的多个结果。 

小结: 

第一种匹配需要学习NSPredicate的写法,需要查阅苹果相关技术文档;如果只关心第一个匹配的结果,第二种匹配较为简洁;如果需要匹配多个结果,同时匹配多次,第三种方式效率会更高

转载自:http://my.oschina.net/pljhonglu/blog/199197


初始化完毕正则表达式的处理类后,我们需要进行正则表达式的查询,IOS官方提供了两种模式:

1、带block模式的方法:

- (void)enumerateMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range usingBlock:(void (^)(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop))block;

使用举例:

?
1
2
3
4
NSRegularExpression * regex = [[NSRegularExpression alloc]initWithPattern:@ "[a-z]"  options:NSRegularExpressionCaseInsensitive error:nil];
     [regex enumerateMatchesInString:@ "124a"  options:NSMatchingReportProgress range:NSMakeRange(0, 4) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags,  BOOL  *stop) {
         NSLog(@ "%@" ,result);
     } ];

注意:1、这个函数的一个参数options是一个枚举,设置回调的方式,如下:

?
1
2
3
4
5
6
7
typedef  NS_OPTIONS(NSUInteger, NSMatchingOptions) {
    NSMatchingReportProgress         = 1 << 0,  //找到最长的匹配字符串后调用block回调
    NSMatchingReportCompletion       = 1 << 1,  //找到任何一个匹配串后都回调一次block
    NSMatchingAnchored               = 1 << 2,  //从匹配范围的开始出进行极限匹配
    NSMatchingWithTransparentBounds  = 1 << 3,  //允许匹配的范围超出设置的范围
    NSMatchingWithoutAnchoringBounds = 1 << 4   //禁止^和$自动匹配行还是和结束
};

            2、block回调中的flags枚举对应如下:

?
1
2
3
4
5
6
7
typedef  NS_OPTIONS(NSUInteger, NSMatchingFlags) {
    NSMatchingProgress               = 1 << 0,  //匹配到最长串是被设置     
    NSMatchingCompleted              = 1 << 1,  //全部分配完成后被设置    
    NSMatchingHitEnd                 = 1 << 2,  //匹配到设置范围的末尾时被设置   
    NSMatchingRequiredEnd            = 1 << 3,  //当前匹配到的字符串在匹配范围的末尾时被设置     
    NSMatchingInternalError          = 1 << 4   //由于错误导致的匹配失败时被设置   
};

            3、还有一点需要注意,就是那个bool值stop,我们可以在block块中设置它为YES,之后便会停止查找。

2、非block的方法

这个方法会返回一个结果数组,将所有匹配的结果返回

- (NSArray *)matchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;

这个方法会返回匹配到得字符串的个数
- (NSUInteger)numberOfMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;

这个方法会返回第一个查询到得结果,这个NSTextCheckingResult对象中有一个range属性,可以得到匹配到的字符串的范围。
- (NSTextCheckingResult *)firstMatchInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;

这个方法直接返回匹配到得范围,NSRange。
- (NSRange)rangeOfFirstMatchInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;


三、一个辅助方法

NSRegularExpression类中还提供了一个辅助方法:

+ (NSString *)escapedPatternForString:(NSString *)string;


它可以帮助我们将正则表达式加上"\"进行保护,将元字符转化成字面值。