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;
}
@結果:

發佈了6 篇原創文章 · 獲贊 0 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章