美文网首页精品文章正则表达式iOS技术专题
iOS开发 -正则表达式的使用和匹配内容

iOS开发 -正则表达式的使用和匹配内容

作者: Raybon_lee | 来源:发表于2016-03-15 18:18 被阅读1117次

    我们经常会遇到验证一个用户的操作数据是否合法,我们最好的方式是用正则去检测用户的行为操作是否正确

    来个图片放松一下啊来个图片放松一下啊

    正则匹配整数和浮点数

    需求:检测文本中的数字,并改变颜色,数字都是序列化的样式文本:当前已经使用的存储
    空间大小为3.2GB,下载文件占用788MB,还剩余6.7GB空间,总容量为12GB.
    我们需要匹配出来一下几个数字
    3.2GB 
    788MB
    6.7GB
    12GB
    

    我们如果第一眼看上去你觉得要如何去做呢,我们今天要的不仅是匹配,还要获取到对应的数值
    这个匹配我们使用系统的NSRegularExpression ,进行内容的匹配,开始我想到了三种规则:如下

    1. \\d*\\.\\d*[M|G]B 这种规则只适合含有小数点的数值,等到项目中用的时候才发现整数没有匹配上去,继续修改下面
    2. (((\\d*\\.\\d*)MB)|((\\d*\\.\\d*)GB)) 这个是一位PHP大牛写的,我仔细分解了一下,似乎我写的那个就可以了,但是还是匹配到整数就错误。
    3. (\\d*(\\.\\d*)?)[M|G]B 这个才是我们想要的,既能匹配小数,又可以匹配整数,这个是我考虑之后稍作修改,检测结果是正常的

    第三种情况的匹配代码实例如下:

        NSString *searchText = @"当前手机已使用存储大小为3.2GB,已下载文件占用899MB,剩余空间大小5.8GB,当前总容量为12GB";
        NSError *error = NULL;
        //@"\\d*\\.\\d*[M|G]B"   匹配字符串中连续规则的数字序列
        //@"(((\\d*\\.\\d*)MB)|((\\d*\\.\\d*)GB))"  匹配规则全部序列
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\d*(\\.\\d*)?)[M|G]B" 
        options:NSRegularExpressionCaseInsensitive error:&error];
        NSTextCheckingResult *result = [regex firstMatchInString:searchText options:0 range:NSMakeRange(0, [searchText length])];
        NSArray * matches1 = [regex matchesInString:searchText options:NSMatchingReportProgress range:NSMakeRange(0, [searchText length])];
        for (NSTextCheckingResult * test in matches1) {
           
            NSString *tagValuestr = [searchText substringWithRange:test.range];
             NSLog(@"tagvalue = %@",tagValuestr);
        }
        if (result) {
            NSLog(@"%@", [searchText substringWithRange:result.range]);
        }
    
    

    控制台输出结果为:

    2016-03-15 17:41:19.608 RegularExp[54814:2551313] tagvalue = 3.2GB
    2016-03-15 17:41:19.608 RegularExp[54814:2551313] tagvalue = 899MB
    2016-03-15 17:41:19.608 RegularExp[54814:2551313] tagvalue = 5.8GB
    2016-03-15 17:41:19.608 RegularExp[54814:2551313] tagvalue = 12GB
    2016-03-15 17:41:19.609 RegularExp[54814:2551313] 3.2GB
    
    

    我们可以发现,这个就是我们想要的结果
    result 是单个结果,使用matches是获取多个结果

    我们再说一下获取URL参数的正则

    代码如下:

     NSError *error1;
        NSString *regTags=[[NSString alloc] initWithFormat:@"(^|&|\\?)+%@=+([^&]*)(&|$)",@"adc"];
        NSRegularExpression *regex1 = [NSRegularExpression regularExpressionWithPattern:regTags
                                                                               options:NSRegularExpressionCaseInsensitive
                                                                                 error:&error1];
        
        // 执行匹配的过程
         NSString *webaddress=@"http://www.baidu.com/dd/adb.htm?adc=e12&xx=lkw&dalsjd=12";
        NSArray *matches = [regex1 matchesInString:webaddress
                                          options:0
                                            range:NSMakeRange(0, [webaddress length])];
        for (NSTextCheckingResult *match in matches) {
            //NSRange matchRange = [match range];
            //NSString *tagString = [webaddress substringWithRange:matchRange];  // 整个匹配串
            //        NSRange r1 = [match rangeAtIndex:1];
            //        if (!NSEqualRanges(r1, NSMakeRange(NSNotFound, 0))) {    // 由时分组1可能没有找到相应的匹配,用这种办法来判断
            //            //NSString *tagName = [webaddress substringWithRange:r1];  // 分组1所对应的串
            //            return @"";
            //        }
            
            NSString *tagValue = [webaddress substringWithRange:[match rangeAtIndex:2]];  // 分组2所对应的串
            //    NSLog(@"分组2所对应的串:%@\n",tagValue);
            NSLog(@"tagvalue = %@",tagValue);
            
        }
    
    

    控制台的输出

    2016-03-15 17:41:19.609 RegularExp[54814:2551313] tagvalue = e12
    

    以上是对NSRegularExpression 这个类的使用

    下面我们扩展一些实用的东西:

    方法一、 使用谓词NSPredicate创建正则表达式

    一般我们只使用谓词仅供开发者判断用户输入的字符串是否合法,并没有其他要求

    // 编写正则表达式:只能是数字或英文,或两者都存在
    NSString *regex = @"^[a-z0-9A-Z]*$";
    // 创建谓词对象并设定条件的表达式
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    // 判断的字符串
    NSString *str = @"Hello100";
    // 对字符串进行判断
    if ([predicate evaluateWithObject:str]) {
        NSLog(@"Match");
    }
    

    上面判断之后的结果就是会输出 Match ,如果我们替换一下字符串为-、= ! 之类的,那么判断就不会进入。

    方法二、 通过NSRegularExpression 获取指定的对象

    我们可以过滤掉一些东西获取到我们想要的结果,代码更清晰:

    NSString *url = @"8888@163.com";
    NSError *error;
    // 创建NSRegularExpression对象并指定正则表达式
    NSRegularExpression *regex = [NSRegularExpression
                    regularExpressionWithPattern:@"[^@]*\\."
                    options:0
                    error:&error];
    if (!error) { // 如果没有错误
      // 获取特特定字符串的范围
      NSTextCheckingResult *match = [regex firstMatchInString:url
                              options:0
                                range:NSMakeRange(0, [url length])];
      if (match) {
        // 截获特定的字符串
        NSString *result = [url substringWithRange:match.range];
        NSLog(@"%@",result);
      }
    } else { // 如果有错误,则把错误打印出来
      NSLog(@"error - %@", error);
    }
    

    上面这个列子我们是从特定字符串中检索以“@”开头 “.” 结尾的区间字符串,所以最终获取到的字符串结尾包括点“.”,最终输出的是“163.”;

    方法三、NSRegularExpression 获取多个结果,也就是最上面我们的需求

    我们讲解一个获取连续数字序列的正则

    NSString *regex = @"\\-\\d*\\.";
    NSString *str = @"-111.-666.-888.";
    NSError *error;
    NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:regex
                                                                             options:NSRegularExpressionCaseInsensitive
                                                                               error:&error];
    // 对str字符串进行匹配
    NSArray *matches = [regular matchesInString:str
                                        options:0
                                          range:NSMakeRange(0, str.length)];
    // 遍历匹配后的每一条记录
    for (NSTextCheckingResult *match in matches) {
        NSRange range = [match range];
        NSString *mStr = [str substringWithRange:range];
        NSLog(@"%@", mStr);
    }
    

    @"\\-\\d*\\.";我们这里的规则是-号开头,\ 代表特殊字符转义,不参与匹配,“\d” 相当于 [0-9] ,有\ 开始的规则,需要加入转义字符“、”
    方法三的输出结果是

    -111.
    -666.
    -888.
    

    通过打印结果,我们可以得知,我们通过方法三的结果是多个,获取到我们想要的结果。

    注:我们把常用的字符注释一下

    1. “\” :将下一个字符标记为一个特殊字符、或一个原义字符、或者一个向后引用,或者一个八进制转义符。例如:“\\n”匹配“\n” "\n"。序列“\\” 匹配“\” 而 “\(” 匹配“(”
    2. "^": 匹配输入字符串的开始位置,如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
    3. "$" : 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
    4. "*": 匹配前面的子表达式零次或多次(大于等于0次)。例如,zo*能匹配“z”,“zo”以及“zoo”。*等价于{0,}。
    5. "+":匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
    6. "?": 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。
    7. "{n}":n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
    8. "{n,}":n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
    9. "{n,m}":m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
    10. "?":当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。
    11. ".":匹配除“\r\n”之外的任何单个字符。要匹配包括“\r\n”在内的任何字符,请使用像“[\s\S]”的模式。
    12. "\s" :"匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。"

    正则先说到这里,请查看链接:正则使用说明

    相关文章

      网友评论

      本文标题:iOS开发 -正则表达式的使用和匹配内容

      本文链接:https://www.haomeiwen.com/subject/jzhqlttx.html