iOS中的正規表示式

weixin_33907511發表於2016-03-05

在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);
另一種是命名捕獲組,語法規則:(?<name>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 組的概念

相關文章