macOS/iOS API解説

iOS , Mac アプリケーション開発のために使われる主要フレームワークの日本語情報です。2010年代に書かれた内容です。今後更新はありません。

目次

NSRegularExpressionクラス

INDEX>Foundation>NSRegularExpression

apple(OS X)
apple(iOS)

解説

正規表現クラス

継承 NSObject
準拠 NSCoding
NSCopying
NSObject (NSObject)
フレームワーク /System/Library/Frameworks/Foundation.framework
使用可能 OS X 10.7以降
iOS 4.0以降
定義 NSRegularExpression.h

概要

本クラスについて

正規表現と呼ばれる式を使ってテキストを検索・置換するメカニズムがありそれを実現するクラスです。
Unicode用国際化コンポーネントICU正規表現コー
文字列の中から特定のパターン検索しその部分を置換することができます。たとえばhttp://www...とある部分を探し出してその部分をリンクとして認識させるような場合の文字の抽出に使うことができます。
サンプルにもありますが URLのクエリー?aaa=100&bbb=200の取り出しなどにも使うことができます。

正規表現クラスの作成

テキストで正規表現クラスを作成するには(+ regularExpressionWithPattern:options:error)メソッドを使用します。allocで作成した正規表現クラスを初期化するには(– initWithPattern:options:error)メソッドを使用します。

正規表現を使って、URLのxxx=xxxという部分を取り出すサンプル

#pragma mark -enumerateMatchesInString:options:range:usingBlock:
-(void)method001
{
    NSError *aError = nil;
	NSString *str = @"http://www.oomori.com?name=oomori&age=44";
    NSRegularExpression *regExp = [NSRegularExpression regularExpressionWithPattern:@"([\\w]+)=([\\w]+)" 
                                                                            options:NSRegularExpressionCaseInsensitive
                                                                              error:&aError];
     __block NSMutableDictionary *muDic =  [NSMutableDictionary dictionaryWithCapacity:0];
    [regExp enumerateMatchesInString:str 
                             options:NSMatchingReportProgress 
                               range:NSMakeRange(0,[str length]) 
                          usingBlock:
     ^(NSTextCheckingResult *result ,NSMatchingFlags flags,BOOL *stop )
     {
         if (!(flags & NSMatchingProgress)) {
             NSString *aKey = [str substringWithRange:[result rangeAtIndex:1]];
             NSString *aValue = [str substringWithRange:[result rangeAtIndex:2]];
             [muDic setObject:aValue forKey:aKey];
         }
     }
     
     ];
    NSLog(@"%s%@",__FUNCTION__,[muDic description]);
    //=>-[OOOAppDelegate method001]{age = 44;name = oomori;}
}

正規表現とオプションの取得

正規表現パターンを取得するには(pattern)プロパティを参照します。(読み取り専用)大文字小文字を無視するなどオプションを取得するには(options)プロパティを参照します。(読み取り専用)キャプチャグループ数を取得するには(numberOfCaptureGroups)プロパティを参照します。(読み取り専用)

正規表現を使った文字列の検索

マッチする項目がいくつあるかを取得するには(– numberOfMatchesInString:options:range)メソッドを使用します。

マッチする項目を順に処理するためには(– enumerateMatchesInString:options:range:usingBlock)メソッドを使用します。

マッチする項目の情報を配列で取得するには(– matchesInString:options:range)メソッドを使います。
NSTextCheckingResultの配列で返されます。

#pragma mark NSRegularExpression  regularExpressionWithPattern:
-(void)method003
{
    
	NSString *str = @"abcdefg555hijklmn8972opqrstu";
    NSRegularExpression *regExp = [NSRegularExpression regularExpressionWithPattern:@"\\d+" options:NSRegularExpressionCaseInsensitive error:nil];
    NSArray *resultArray = [regExp matchesInString:str
                                                options:0
                                                  range:NSMakeRange(0, [str length])];
    
    [resultArray enumerateObjectsWithOptions:NSEnumerationConcurrent //並列
                              usingBlock:^(id obj,NSUInteger idx,BOOL *stop){
                                  NSTextCheckingResult *tcResult = (NSTextCheckingResult *)obj;
                                  NSLog(@"%s %@ %u-%u",__FUNCTION__,tcResult.regularExpression,tcResult.range.location,tcResult.range.length );
                                  return;
                                  
                              }];
    //=><NSRegularExpression: 0x6d4e7c0> \d+ 0x1 7-3
    //=><NSRegularExpression: 0x6d4e7c0> \d+ 0x1 17-4
    
}

最初にマッチする項目の情報を取得するには(– firstMatchInString:options:range)メソッドを使用します。最初にマッチする項目の範囲を取得するには(– rangeOfFirstMatchInString:options:range)メソッドを使用します。

正規表現を使っての置換

変更可能な文字列を、正規表現を使ってマッチした文字列を別の文字列に置換するには(– replaceMatchesInString:options:range:withTemplate)メソッドを使用します。
置換した数が返されます。
変更不可な文字列を、正規表現を使ってマッチした文字列を別の文字列に置換した新しい文字列として返すには(– stringByReplacingMatchesInString:options:range:withTemplate)メソッドを使います。

文字列のエスケープ

テンプレート内では$などの文字は置換用の$0、$1などに使われるためそのままでは使用できません。例えば$を\$に変えるように文字をエスケープするときに使うメソッドが(+ escapedTemplateForString)です。同様にパターン用にも(+ escapedPatternForString)というメソッドが用意されています。

カスタムの置換

カスタマイズした方法で置換するには(– replacementStringForResult:inString:offset:template)メソッドを使用します。

#pragma mark NSRegularExpression  stringByReplacingMatchesInString:
-(void)method009
{
    
	NSError* error = nil;
    NSRegularExpression* regularExpression = [NSRegularExpression
                                  regularExpressionWithPattern:@"\\b[1-3]\\b"
                                  options:NSRegularExpressionCaseInsensitive
                                  error:&error];

    NSString* aString = @"1  2  3";
    
    NSMutableString* mutableString = [aString mutableCopy];
    NSInteger offset = 0;
    
    for (NSTextCheckingResult* result in [regularExpression matchesInString:aString
                                                        options:0
                                                          range:NSMakeRange(0, [aString length])]) {
        
        NSRange resultRange = [result range];
        resultRange.location += offset; 
        NSString* match = [regularExpression replacementStringForResult:result
                                                   inString:mutableString
                                                     offset:offset
                                                   template:@"$0"];
        NSString* replacement;
        if ([match isEqualToString:@"1"]) {
            replacement = @"Jan";
        } else if ([match isEqualToString:@"2"]) {
            replacement = @"Feb";
        } else if ([match isEqualToString:@"3"]) {
            replacement = @"Mar";
        }
        
        [mutableString replaceCharactersInRange:resultRange withString:replacement];
        
        offset += ([replacement length] - resultRange.length);
    }
    
    NSLog(@"%s %@",__FUNCTION__,mutableString  );
    //=>
    
}