2

I want extract parts of a string with NSRegularExpression.

For example, I have this string:

@"1   UIKit                               0x00540c89 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163";

And I want extract "UIKit", "0x00540c89", "UIApplication", "_callInitializationDelegatesForURL:payload:suspended:" and "1163".

I have maked the regular expression:

@"^[0-9]+\\s+[a-zA-Z]+\\s+0x[0-9a-zA-Z]+\\s+\\-\\s*\\[[a-zA-Z]+\\s+[_:a-zA-Z]+\\]\\s+\\+\\s+[0-9]+"

But I dont know how I have to do this. It is possible.

    NSString *origen = @"1   UIKit                               0x00540c89 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163";
    // Setup an NSError object to catch any failures
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[0-9]+\\s+[a-zA-Z]+\\s+0x[0-9a-zA-Z]+\\s+\\-\\s*\\[[a-zA-Z]+\\s+[_:a-zA-Z]+\\]\\s+\\+\\s+[0-9]+" 
                                                                           options:NSRegularExpressionCaseInsensitive 
                                                                             error:&error];
    // create an NSRange object using our regex object for the first match in the string
    NSRange rangeOfFirstMatch = [regex rangeOfFirstMatchInString:origen options:0 range:NSMakeRange(0, [origen length])];
    // check that our NSRange object is not equal to range of NSNotFound
    if (!NSEqualRanges(rangeOfFirstMatch, NSMakeRange(NSNotFound, 0))) {
        // Since we know that we found a match, get the substring from the parent string by using our NSRange object
        NSString *substringForFirstMatch = [origen substringWithRange:rangeOfFirstMatch];
        NSLog(@"Extracted: %@",substringForFirstMatch);
    }
Alan Moore
  • 73,866
  • 12
  • 100
  • 156
intropedro
  • 2,804
  • 1
  • 24
  • 25

2 Answers2

3

Try This :

NSCharacterSet *separatorSet = [NSCharacterSet characterSetWithCharactersInString:@" -[]+?.,"];
NSMutableArray *array = [origen  componentsSeparatedByCharactersInSet:separatorSet];
[array removeObject:@""];
Hector
  • 3,909
  • 2
  • 30
  • 46
3

You obviously need a way to match multiple ranges with your regular expression. This is done with matching groups that are indicated with parentheses. Then you can use one of the NSRegularExpression methods that give you a NSTextCheckingResult instead of a simple range. An NSTextCheckingResult can contain multiple ranges.

Example:

NSString *pattern = @"^[0-9]+\\s+([a-zA-Z]+)\\s+(0x[0-9a-zA-Z]+)\\s+\\-\\s*(\\[[a-zA-Z]+\\s+[_:a-zA-Z]+\\])\\s+\\+\\s+([0-9]+)";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern 
                                                                       options:NSRegularExpressionCaseInsensitive 
                                                                         error:&error];

NSTextCheckingResult *firstResult = [regex firstMatchInString:origen options:0 range:NSMakeRange(0, origen.length)];
if ([firstResult numberOfRanges] == 5) {
    //The range at index 0 contains the entire string.
    NSLog(@"1: '%@'", [origen substringWithRange:[firstResult rangeAtIndex:1]]);
    NSLog(@"2: '%@'", [origen substringWithRange:[firstResult rangeAtIndex:2]]);
    NSLog(@"3: '%@'", [origen substringWithRange:[firstResult rangeAtIndex:3]]);
    NSLog(@"4: '%@'", [origen substringWithRange:[firstResult rangeAtIndex:4]]);
}
omz
  • 53,243
  • 5
  • 129
  • 141