NSRegularExpression

我只是一个虾纸丫 提交于 2019-12-03 22:42:10

You shouldn't use a regex for this, specially if you don't know how. Compare:

NSString *string = @"?name=Johon&key=123%252Bf-34Fa";
// NSString *string = @"?key=123%252Bf-34Fa&name=John";

// one way
NSRange range = [string rangeOfString:@"key="];
if (range.location!=NSNotFound){
    string = [string substringFromIndex:NSMaxRange(range)];
    range = [string rangeOfString:@"&"];
    if (range.location!=NSNotFound){
        string = [string substringToIndex:range.location];
    }
}

// another way
__block NSString *keyValue = nil;
[[string componentsSeparatedByString:@"&"] enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop){
    NSRange range = [object rangeOfString:@"key="];
    if (range.location!=NSNotFound){
        keyValue = [object substringFromIndex:range.location+range.length];
        *stop = YES;
    }
}];

// regex way
NSString *regexStr = @"[\\?&]key=([^&#]*)";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexStr options:0 error:&error];
// enumerate all matches
if ((regex==nil) && (error!=nil)){
    NSLog( @"Regex failed for url: %@, error was: %@", string, error);
} else {
    [regex enumerateMatchesInString:string 
                            options:0 
                              range:NSMakeRange(0, [string length]) 
                         usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop){
                             if (result!=nil){
                                 // iterate ranges
                                 for (int i=0; i<[result numberOfRanges]; i++) {
                                     NSRange range = [result rangeAtIndex:i];
                                     NSLog(@"%ld,%ld group #%d %@", range.location, range.length, i, 
                                           (range.length==0 ? @"--" : [string substringWithRange:range]));
                                 }
                             }
                         }];
}

I know it's been years since the answer was posted, but while the code in Jano's answer is technically correct, calling rangeOfString multiple time is very inefficient.

The regex is actually quite simple. You can do one of the two following:

key=([^&\s]+) // searches for the key
              // matches all characters other than whitespace characters
              //   and ampersands
([^&?\s]+)=([^&\s]+)  // searches for key/value pairs
                      // key matches all characters other than whitespace characters
                      //   and ampersands and question marks
                      // value matches all characters other than whitespace characters
                      //   and ampersands

The code in Objective-C using NSRegularExpression would look like this:

NSString *stringToSearch = @"?name=John&key=123%252Bf-34Fa"

NSError *error;
NSRegularExpression *findKey = [NSRegularExpression regularExpressionWithPattern:@"key=([^&\\s]+)" options:0 error:&error];
if (error) {
    // log error
}

NSString *keyValue;
NSTextCheckingResult *match = [findKey firstMatchInString:stringToSearch options:0 range:NSMakeRange(0, stringToSearch.length)];
if (match) {
    NSRange keyRange = [match rangeAtIndex:1];
    keyValue = [stringToSearch substring:keyRange];
}

or like this:

NSString *stringToSearch = @"?name=John&key=123%252Bf-34Fa"

NSError *error;
NSRegularExpression *findParameters = [NSRegularExpression regularExpressionWithPattern:@"([^&?\\s]+)=([^&\\s]+)" options:0 error:&error];
if (error) {
    // log error
}

NSMutableDictionary *keyValuePairs = [[NSMutableDictionary alloc] init];
NSArray *matches = [findParameters matchesInString:stringToSearch options:0 range:NSMakeRange(0, stringToSearch.length)];
for (NSTextCheckingResult *match in matches) {
    NSRange keyNameRange = [match rangeAtIndex:1];
    NSRange keyValueRange = [match rangeAtIndex:2];
    keyValuePairs[[stringToSearch substring:keyNameRange]] = [stringToSearch substring:keyValueRange];
}

Note the double backslash (\\) to escape the backslash when using the regex in actual code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!