I need NSRange objects for the position of each uppercase letter in a given NSString for input into a method for a custom attributed string class.
There are of course q
Using RegexKitLite 4.0+ with a runtime that supports Blocks, this can be quite zippy:
NSString *string = @"A simple String to TEST for Upper Case Letters.";
NSString *regex = @"\\p{Lu}";
[string enumerateStringsMatchedByRegex:regex options:RKLNoOptions inRange:NSMakeRange(0UL, [string length]) error:NULL enumerationOptions:RKLRegexEnumerationCapturedStringsNotRequired usingBlock:^(NSInteger captureCount, NSString * const capturedStrings[captureCount], const NSRange capturedRanges[captureCount], volatile BOOL * const stop) {
NSLog(@"Range: %@", NSStringFromRange(capturedRanges[0]));
}];
The regex \p{Lu}
says "Match all characters with the Unicode property of 'Letter' that are also 'Upper Case'".
The option RKLRegexEnumerationCapturedStringsNotRequired
tells RegexKitLite that it shouldn't create NSString
objects and pass them via capturedStrings[]
. This saves quite a bit of time and memory. The only thing that gets passed to the block is the NSRange
values for the match via capturedRanges[]
.
There are two main parts to this, the first is the RegexKitLite method:
[string enumerateStringsMatchedByRegex:regex
options:RKLNoOptions
inRange:NSMakeRange(0UL, [string length])
error:NULL
enumerationOptions:RKLRegexEnumerationCapturedStringsNotRequired
usingBlock:/* ... */
];
... and the second is the Block that is passed as an argument to that method:
^(NSInteger captureCount,
NSString * const capturedStrings[captureCount],
const NSRange capturedRanges[captureCount],
volatile BOOL * const stop) { /* ... */ }