NSRegularExpression iOS自带的正则表达式

转载自

NSRegularExpression iOS自带的正则表达式


以前做验证邮箱,电话号码的时候通常用第三方的正则表达式或者NSPredicate(点这里查看以前的文章),在后期,苹果推出了自己的正则表达式来提供给开发者调用,很方便,功能也强大.

      具体可以查看官方文档,包括如何书写进行匹配的正则表达式例子,这里我就不多加详述了,因为本人看那一堆符号好烦.....只好直接求助于谷歌了,下面只给出几个常用的.

#define KPhoneRegex  @"\\d{3}-\\d{8}|\\d{3}-\\d{7}|\\d{4}-\\d{8}|\\d{4}-\\d{7}|1+[358]+\\d{9}|\\d{8}|\\d{7}"
#define KWebRegex    @"((http[s]{0,1}|ftp)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)"
#define KWebOtherRegex @"http+:[^\\s]*"
#define KEmailRegex  @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"

/**
     1. 返回所有匹配结果的集合(适合,从一段字符串中提取我们想要匹配的所有数据)
     *  - (NSArray *)matchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;
     2. 返回正确匹配的个数(通过等于0,来验证邮箱,电话什么的,代替NSPredicate)
     *  - (NSUInteger)numberOfMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;
     3. 返回第一个匹配的结果。注意,匹配的结果保存在  NSTextCheckingResult 类型中
     *  - (NSTextCheckingResult *)firstMatchInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;
     4. 返回第一个正确匹配结果字符串的NSRange
     *  - (NSRange)rangeOfFirstMatchInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;
     5. block方法
     *  - (void)enumerateMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range usingBlock:(void (^)(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop))block;
     */
    
    /**
     *  enum {
     NSRegularExpressionCaseInsensitive             = 1 << 0,   // 不区分大小写的
     NSRegularExpressionAllowCommentsAndWhitespace  = 1 << 1,   // 忽略空格和# -
     NSRegularExpressionIgnoreMetacharacters        = 1 << 2,   // 整体化
     NSRegularExpressionDotMatchesLineSeparators    = 1 << 3,   // 匹配任何字符,包括行分隔符
     NSRegularExpressionAnchorsMatchLines           = 1 << 4,   // 允许^和$在匹配的开始和结束行
     NSRegularExpressionUseUnixLineSeparators       = 1 << 5,   // (查找范围为整个的话无效)
     NSRegularExpressionUseUnicodeWordBoundaries    = 1 << 6    // (查找范围为整个的话无效)
     };
     typedef NSUInteger NSRegularExpressionOptions;
     */
    
    // 下面2个枚举貌似都没什么意义,除了在block方法中,一般情况下,直接给0吧
    /**
     *  enum {
     NSMatchingReportProgress         = 1 << 0,
     NSMatchingReportCompletion       = 1 << 1,
     NSMatchingAnchored               = 1 << 2,
     NSMatchingWithTransparentBounds  = 1 << 3,
     NSMatchingWithoutAnchoringBounds = 1 << 4
     };
     typedef NSUInteger NSMatchingOptions;
     */
    
    /** 此枚举值只在5.block方法中用到
     *  enum {
     NSMatchingProgress               = 1 << 0,
     NSMatchingCompleted              = 1 << 1,
     NSMatchingHitEnd                 = 1 << 2,
     NSMatchingRequiredEnd            = 1 << 3,
     NSMatchingInternalError          = 1 << 4
     };
     typedef NSUInteger NSMatchingFlags;
     */
    

    // 测试字符串,把里面的电话号码解析出来
    NSString *urlString = @"哈哈哈哈呵呵呵s15279107723在这里啊啊啊啊s15279107716";
    NSError *error = NULL;
    // 根据匹配条件,创建了一个正则表达式(类方法,实例方法类似)
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:KPhoneRegex options:NSRegularExpressionCaseInsensitive error:&error];
    if (regex != nil) {
        // 3.....
        NSTextCheckingResult *firstMatch = [regex firstMatchInString:urlString
                                                             options:0
                                                            range:NSMakeRange(0, [urlString length])];
        if (firstMatch) {
            NSRange resultRange = [firstMatch rangeAtIndex:0];
            //从urlString中截取数据
            NSString *result = [urlString substringWithRange:resultRange];
            NSLog(@"result = %@",result);
        }
        // 2.....
        NSUInteger number = [regex numberOfMatchesInString:urlString
                                                   options:0
                                                   range:NSMakeRange(0, [urlString length])];
        NSLog(@"number = %ld",number);
        // 5.....(坑爹的返回第一个匹配结果)
        [regex enumerateMatchesInString:urlString options:0 range:NSMakeRange(0, [urlString length]) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
            NSLog(@"---%@",NSStringFromRange([result range]));
            if (flags != NSMatchingInternalError) {
                NSRange firstHalfRange = [result rangeAtIndex:0];
                if (firstHalfRange.length > 0) {
                    NSString *resultString1 = [urlString substringWithRange:firstHalfRange];
                    NSLog(@"result1 = %@",resultString1);
                }
            }
            *stop = YES;
        }];
    }
    
    // 替换掉你要匹配的字符串
    NSString *reString = [regex stringByReplacingMatchesInString:urlString
                                                        options:0
                                                        range:NSMakeRange(0, [urlString length])
                                                        withTemplate:@"(我就是替换的值)"];
    NSLog(@"reString = %@",reString);
    // 还有2个方法大家可以去尝试看看
    
    
    // 1.
    NSMutableArray *oneArray = [self _matchLinkWithStr:urlString withMatchStr:KPhoneRegex];
    for (NSString *phone in oneArray) {
        NSLog(@"phone = %@",phone);
    }

// 1.....
- (NSMutableArray *)_matchLinkWithStr:(NSString *)str withMatchStr:(NSString *)matchRegex;
{
    NSError *error = NULL;
    NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:matchRegex
                                                                         options:NSRegularExpressionCaseInsensitive
                                                                           error:&error];
    NSArray *match = [reg matchesInString:str
                                  options:NSMatchingReportCompletion
                                  range:NSMakeRange(0, [str length])];
    
    NSMutableArray *rangeArr = [NSMutableArray array];
    // 取得所有的NSRange对象
    if(match.count != 0)
    {
        for (NSTextCheckingResult *matc in match)
        {
            NSRange range = [matc range];
            NSValue *value = [NSValue valueWithRange:range];
            [rangeArr addObject:value];
        }
    }
    // 将要匹配的值取出来,存入数组当中
    __block NSMutableArray *mulArr = [NSMutableArray array];
    [rangeArr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSValue *value = (NSValue *)obj;
        NSRange range = [value rangeValue];
        [mulArr addObject:[str substringWithRange:range]];
    }];
    return mulArr;
}


replacementStringForResult

 NSError* errorx = NULL;
    NSRegularExpression* regexx = [NSRegularExpression
                                   regularExpressionWithPattern:@"\\b[1-3]\\b"
                                   options:NSRegularExpressionCaseInsensitive
                                   error:&errorx];
    
    NSString* yourString = @"This is the input string where i want to replace 1 2 & 3";
    
    NSMutableString* mutableString = [yourString mutableCopy];
    NSInteger offset = 0; // keeps track of range changes in the string
    // due to replacements.
    for (NSTextCheckingResult* result in [regexx matchesInString:yourString
                                                         options:0
                                                           range:NSMakeRange(0, [yourString length])]) {
        
        NSRange resultRange = [result range];
        resultRange.location += offset; // resultRange.location is updated
        // based on the offset updated below
        
        // implement your own replace functionality using
        // replacementStringForResult:inString:offset:template:
        // note that in the template $0 is replaced by the match
        NSString* match = [regexx replacementStringForResult:result
                                                    inString:mutableString
                                                      offset:offset
                                                    template:@"$0"];
        NSString* replacement;
        if ([match isEqualToString:@"1"]) {
            replacement = @"ONE";
        } else if ([match isEqualToString:@"2"]) {
            replacement = @"TWO";
        } else if ([match isEqualToString:@"3"]) {
            replacement = @"THREE";
        }
        
        // make the replacement
        [mutableString replaceCharactersInRange:resultRange withString:replacement];
        
        // update the offset based on the replacement
        offset += ([replacement length] - resultRange.length);
    }
    
    NSLog(@"mutableString: %@", mutableString); 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值