NSRegularExpression - PullRequest
       3

NSRegularExpression

1 голос
/ 16 сентября 2011

У меня есть строка вроде:


?key=123%252Bf-34Fa&name=John
?name=Johon&key=123%252Bf-34Fa

Я хочу получить значение для key, я использую это NSRegularExpression (?i)(?<=key=)[.?!&]+[?=&]?? Я думаю, что этот шаблон похож на сопоставление с любым символом, кроме «&».

значение каждой клавиши может иметь что угодно, кроме "&". Итак, как я могу создать правильное NSRegularExpression? спасибо.

Ответы [ 2 ]

8 голосов
/ 16 сентября 2011

Вы не должны использовать регулярные выражения для этого, особенно если вы не знаете, как. Для сравнения:

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]));
                                 }
                             }
                         }];
}
0 голосов
/ 27 августа 2014

Я знаю, что прошло много лет с тех пор, как ответ был опубликован, но хотя код в ответе Яно технически верен, многократный вызов rangeOfString неэффективен.

Регулярное выражение на самом деле довольно просто. Вы можете сделать одно из двух следующих действий:

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

Код в Objective-C с использованием NSRegularExpression будет выглядеть так:

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];
}

или как это:

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];
}

Обратите внимание на двойную обратную косую черту (\\), чтобы избежать обратной косой черты при использовании регулярного выражения в реальном коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...