LoginSignup
6
6

More than 5 years have passed since last update.

正規表現にマッチする部分を区切りとしてNSStringを分割

Posted at

ちなみに、以下のようなことをするメソッドはすでにあった。

  • 文字列をデリミタとして分割する
  • 文字集合(NSCharacterSet)にマッチする部分を区切りとして分割する
  • 正規表現にマッチした部分全ての配列を返す。rubyとかでいうところのString#scan。あるいはマッチした部分を引数にとるブロックを実行する。

だけども正規表現にマッチするとこを区切りとして分割するメソッドがなかったので実装してみた。

#import "Foundation/Foundation.h"

@interface NSString (RegularExpression)
// 正規表現で分割した文字列の配列を返す
- (NSArray *)componentsSeparatedByRegularExpression:(NSRegularExpression *)regexp;
// 正規表現で分割した文字列を引数にとるブロックを実行する
- (void)componentsSeparatedByRegularExpression:(NSRegularExpression *)regexp
                                    usingBlock:(void (^)(NSString *))block;
@end

@implementation NSString (RegularExpression)
- (NSArray *)componentsSeparatedByRegularExpression:(NSRegularExpression *)regexp {
    NSMutableArray *result = [NSMutableArray array];
    [self componentsSeparatedByRegularExpression:regexp
                                      usingBlock:^(NSString *component) {
            [result addObject:component];
        }];
    return result;
}

- (void)componentsSeparatedByRegularExpression:(NSRegularExpression *)regexp
                                         usingBlock:(void (^)(NSString *))block {
    __block int startPage = 0;
    [regexp enumerateMatchesInString:self
                             options:0
                               range:NSMakeRange(0, self.length)
                          usingBlock:^(NSTextCheckingResult *match,
                                       NSMatchingFlags flag,
                                       BOOL *stop) {
            NSUInteger matchLocation = match.range.location;
            NSUInteger matchLength   = match.range.length;

            block([self substringWithRange:NSMakeRange(startPage, matchLocation - startPage)]);
            startPage = matchLocation + matchLength;
        }];
    block([self substringWithRange:NSMakeRange(startPage, self.length - startPage)]);
}
@end

// 使用例
int main(int argc, char **argv) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSError *error = nil;
    NSRegularExpression *re =
        [NSRegularExpression regularExpressionWithPattern:@"-{2,}\n"
                                                  options:NSRegularExpressionDotMatchesLineSeparators
                                                    error:&error];
    NSString *text = @""
        "あああ\n"
        "----\n"
        "いいい\n"
        "いいい\n"
        "いいい\n"
        "----\n"
        "いいい\n";

    [text componentsSeparatedByRegularExpression:re
                                      usingBlock:^(NSString *component) {
            NSLog(@"%@", component);
        }];

    for (NSString *component in [text componentsSeparatedByRegularExpression:re]) {
        NSLog(@"%@", component);
    }

    [pool release];

    return 0;
}

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6