Fastest way to get array of NSRange objects for all uppercase letters in an NSString?

后端 未结 4 875
臣服心动
臣服心动 2021-02-10 09:06

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

4条回答
  •  执笔经年
    2021-02-10 09:41

    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) { /* ... */ }
    

提交回复
热议问题