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 组的概念

comments powered by Disqus