yohunl's iOS blog

时间顺流而下,生活逆水行舟

青春是趟回不去的列车


iOS中的正则表达式

在iOS中,系统自带的正则类是 NSRegularExpression

初始化

 + (nullable NSRegularExpression *)regularExpressionWithPattern:(NSString *)pattern options:(NSRegularExpressionOptions)options error:(NSError **)error;

使用实例:

   NSString *text = @"tttt [[UIColor alloc]initWithRed:0.2f  green:2/255  blue:2.0/255 alpha:1] jfkjfkej";
    NSRegularExpression *rgbaUIColorRegex = [NSRegularExpression regularExpressionWithPattern:@"(\\[\\s*UIColor\\s+colorWith|\\[\\s*\\[\\s*UIColor\\s+alloc\\]\\s*initWith)Red:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+green:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+blue:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*alpha:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*\\]" options:NSRegularExpressionCaseInsensitive error:NULL];
    [rgbaUIColorRegex enumerateMatchesInString:text options:0 range:NSMakeRange(0, text.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
        NSRange totalRange = [result range];
        NSLog(@"totalRange = %@,totalPattern = %@",NSStringFromRange(totalRange),[text substringWithRange:totalRange]);
        for (int i = 0; i <= 9; i++) {
            NSString *subStr = nil;
            NSRange range = [result rangeAtIndex:i];
            if (range.location != NSNotFound) {
                subStr = [text substringWithRange:range];

            }
            NSLog(@"pattern Group %d is:%@",i,subStr);
        }

    }];

输出

2016-03-01 07:07:00.503 tttt[10249:271036] totalRange = {5, 68},totalPattern = [[UIColor alloc]initWithRed:0.2f  green:2/255  blue:2.0/255 alpha:1]  
2016-03-01 07:07:00.504 tttt[10249:271036] pattern Group 0 is:[[UIColor alloc]initWithRed:0.2f  green:2/255  blue:2.0/255 alpha:1]  
2016-03-01 07:07:00.504 tttt[10249:271036] pattern Group 1 is:[[UIColor alloc]initWith  
2016-03-01 07:07:00.505 tttt[10249:271036] pattern Group 2 is:0.2f  
2016-03-01 07:07:00.505 tttt[10249:271036] pattern Group 3 is:(null)  
2016-03-01 07:07:00.505 tttt[10249:271036] pattern Group 4 is:2  
2016-03-01 07:07:00.505 tttt[10249:271036] pattern Group 5 is:/255  
2016-03-01 07:07:00.505 tttt[10249:271036] pattern Group 6 is:2.0  
2016-03-01 07:07:00.506 tttt[10249:271036] pattern Group 7 is:/255  
2016-03-01 07:07:00.506 tttt[10249:271036] pattern Group 8 is:1  
2016-03-01 07:07:00.506 tttt[10249:271036] pattern Group 9 is:(null)  

从中我们可以看到[result range] 和 [result rangeAtIndex:0] 是等价的,都是表示匹配完整的正则表达式的的整个字符串 一个NSTextCheckingResult可能包含多个item,你可以使用索引去获取它们 [match rangeAtIndex:0];表示整个的匹配正则的结果 [match rangeAtIndex:1]; (如果存在)表示的是匹配正则中的第一组! 每一次的完整匹配组成一次NSTextCheckingResult *result,什么意思呢 还是举例子说明吧,如果我们的text是 NSString *text = @"[[UIColor alloc]initWithRed:0.23f green:22/255 blue:2.0/255 alpha:1] tttt [[UIColor alloc]initWithRed:0.2f green:2/255 blue:2.0/255 alpha:1] jfkjfkej"
那么 usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) 这个block会进入两次,第一次的结果匹配到的是[[UIColor alloc]initWithRed:0.23f green:22/255 blue:2.0/255 alpha:1],第二次是[[UIColor alloc]initWithRed:0.2f green:2/255 blue:2.0/255 alpha:1]

继续分析上面的示例代码

无论Objective-C还是Swift,你在字面量字符串中都需要转义一些特殊字符(在他们之前添加\字符)。这其中一个字符就是反斜线自身\!既然这个被用来创建正则表达式的模式也是字符串,在你处理String 和 NSRegularExpression,你需要转义反斜线时,在标准的模式串中 . 在OC的模式串定义中,应该是 @“\." 所以你看上面的串

@"(\\[\\s*UIColor\\s+colorWith|\\[\\s*\\[\\s*UIColor\\s+alloc\\]\\s*initWith)Red:"

首先你可以直接简化为标准模式串中的 ([\sUIColor\s+colorWith|[\s[\sUIColor\s+alloc]\sinitWith)Red: 这样有助于你理解

至于各个符号表示啥意思,可以查看标准的正则中的符号意义,这里就不赘述了. 在Swift(或者Objective-C)代码中标准的.将会显示为\. http://www.cnblogs.com/yirlin/archive/2006/04/12/373222.html就有,可以参考

关于模式中的group(组,子组,子模式)

捕获组有两种形式 一种是普通的捕获组,不产生歧义的情况下,后面简称捕获组,语法规则:(expression); 另一种是命名捕获组,语法规则:(?expression)或者(?'name'expression),这两种写法是等价的。 普通捕获组的情况下,捕获组的编号是按照“(”出现的顺序,从左到右,从1开始进行编号的,0表示的是整个 还是看上面的例子

@"(\\[\\s*UIColor\\s+colorWith|\\[\\s*\\[\\s*UIColor\\s+alloc\\]\\s*initWith)Red:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+green:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+blue:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*alpha:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*\\]"

在结果 NSTextCheckingResult *result 中,[result rangeAtIndex:1];表示的是匹配第一个子模式(也就是匹配

(\\[\\s*UIColor\\s+colorWith|\\[\\s*\\[\\s*UIColor\\s+alloc\\]\\s*initWith)

的). 以此类推.

举个更简单的例子

(\d{4})-(\d{2}-(\d\d)) 那么分组的编号是 0 (\d{4})-(\d{2}-(\d\d))
1 (\d{4})
2 (\d{2}-(\d\d))
3 (\d\d)

参考文档

http://www.jianshu.com/p/a784c12c498c NSRegularExpression
http://stackoverflow.com/questions/9276246/how-to-write-regular-expressions-in-objective-c-nsregularexpression group
http://blog.csdn.net/wanglei19880622/article/details/7204492 子模式
http://www.jb51.net/article/19334.htm 组的概念

最近的文章

怎样创建一个xcode插件 第一部分/3部分

本文翻译自 https://www.raywenderlich.com/94020/creating-an-xcode-plugin-part-1 原作者:Derek Selander 译者:@yoh…

继续阅读
更早的文章

xcode7 插件制作入门

概述 我们平时也使用了很多的xcode插件,虽然官方对于插件制作没有提供任何支持,但是加载三方的插件,默认还是被允许的.第三方的插件,需要存放在 ~/Library/Application Suppo…

继续阅读