Skip to content

Instantly share code, notes, and snippets.

@boredzo
Last active April 23, 2016 03:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save boredzo/8640626 to your computer and use it in GitHub Desktop.
Save boredzo/8640626 to your computer and use it in GitHub Desktop.
Category on NSString to enumerate a string's substrings that match another string
#import <Foundation/Foundation.h>
@interface NSString (PRHEnumerateMatches)
- (NSUInteger) enumerateSubstringsMatchingString_PRH:(NSString *)otherString
options:(NSStringCompareOptions)mask
usingBlock:(void (^)(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop))block;
@end
static void test(NSString *stringToFind, NSString *stringToSearch, NSStringCompareOptions options);
int main(int argc, char *argv[]) {
@autoreleasepool {
NSString *stringToFind, *stringToSearch;
stringToFind = @"and";
stringToSearch = @"One, two! One, two! And through and through\n"
@"The vorpal blade went snicker-snack!\n"
@"He left it dead, and with its head\n"
@"He went galumphing back.";
test(stringToFind, stringToSearch, NSCaseInsensitiveSearch);
stringToSearch = @"Hello world!";
stringToFind = @"world!";
test(stringToFind, stringToSearch, 0);
stringToSearch = @"Hello world";
stringToFind = @"world!";
test(stringToFind, stringToSearch, 0);
}
return EXIT_SUCCESS;
}
static void test(NSString *stringToFind, NSString *stringToSearch, NSStringCompareOptions options) {
void (^block)(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) = ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){
NSLog(@"%lu-character string[%lu:%lu] = '%@'", stringToSearch.length, substringRange.location, NSMaxRange(substringRange), substring);
};
NSUInteger count = [stringToSearch enumerateSubstringsMatchingString_PRH:stringToFind
options:options
usingBlock:block];
NSLog(@"Number of matches: %lu", count);
}
@implementation NSString (PRHEnumerateMatches)
- (NSUInteger) enumerateSubstringsMatchingString_PRH:(NSString *)stringToFind
options:(NSStringCompareOptions)mask
usingBlock:(void (^)(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop))block
{
NSUInteger count = 0;
NSUInteger selfLength = self.length;
NSRange searchRange = { 0, selfLength };
NSRange foundRange;
BOOL stop = NO;
while (( ! stop ) && (foundRange = [self rangeOfString:stringToFind options:mask range:searchRange]).location != NSNotFound) {
++count;
if (block != NULL) {
@autoreleasepool {
NSString *substring = [self substringWithRange:foundRange];
block(substring, foundRange, /*TODO include terminators and separators in enclosingRange as described in enumerateSubstringsWithOptions:: docs*/ foundRange, &stop);
}
}
searchRange.location = NSMaxRange(foundRange);
if (searchRange.location >= self.length)
break;
searchRange.length = selfLength - searchRange.location;
}
return count;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment