2015-08-08 3 views
1

Мой код малNSRegularExpression дает неправильный результат от метода numberOfRanges

Создать новый проект XCode и мимо этого кода для запуска:

NSString *stringToCheck = @"## master...origin/master [ahead 1, behind 1]"; 
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\[(ahead) (\\d), (behind) (\\d)\\]|\\[(behind) (\\d)\\]|\\[(ahead) (\\d)\\]" options:0 error:nil]; 

NSArray* matches = [regex matchesInString:stringToCheck options:0 range:NSMakeRange(0, [stringToCheck length])]; 
NSTextCheckingResult *match = [matches firstObject]; 
NSUInteger numberOfRanges = [match numberOfRanges]; 

numberOfRanges им получить = 9. Но should'nt это будет 5?

EDIT: Больше информации данные могут поступать в 3-х формах

1. ## master...origin/master [ahead 1, behind 1] 
2. ## master...origin/master [ahead 1] 
3. ## master...origin/master [behind 1] 

Как я написать код для учета всех 3 сценариев? Не зная, какой матч был найден, я не знаю, как действовать. На основании одного ответа ниже кажется, что [match numberOfRanges] вернет полное совпадение, независимо от того, найден он или нет.

Если данные являются # 1, тогда работает метод [match rangeOfIndex:0-4]. Другие индексы терпят неудачу.

Если данные оказались # 2, тогда работает метод [match rangeOfIndex:5-6]. Другие сбой

Если данные оказались №3, то работает метод [match rangeOfIndex:7-8]. Другие терпят неудачу.

Итак, как мне определить, какая группа была захвачена, поэтому я знаю, какой диапазон поиска?

EDIT: Ответ на основании ответа данного

if ([match rangeAtIndex:1].location != NSNotFound) { // The First capture group 
     aheadCount = [stringToCheck substringWithRange:[match rangeAtIndex:2]]; 
     behindCount = [stringToCheck substringWithRange:[match rangeAtIndex:4]]; 
    } else if ([match rangeAtIndex:5].location != NSNotFound) { //The second Capture group 
     aheadCount = [stringToCheck substringWithRange:[match rangeAtIndex:6]]; 
    } else if ([match rangeAtIndex:7].location != NSNotFound) { //The third capture group 
     behindCount = [stringToCheck substringWithRange:[match rangeAtIndex:8]]; 
    } 

ответ

0

Каждая группа, (...), в шаблоне будет производить диапазон соответствия, как будет весь шаблон (с индексом 0) - дает вам в общей сложности из 9. Использование или, |, не меняет этого, поэтому нумерация остается последовательной - каждая группа имеет уникальный номер.

В вашем примере, если вы исследуете все диапазоны вы увидите, что на матчи 5-го по 8 значение NSRangelocation является NSNotFound, как ваша строка соответствует первой альтернативе, которая содержит группы с 1 по 4.

Примечания: Поскольку каждый группа имеет уникальный номер путем тестирования для NSNotFound, вы можете определить, какая альтернатива была сопоставлена.

+0

Как проверить, какая группа = NSNotFound? Я пробовал такой цикл while, но он не работал -> 'while ((aRange = [match rangeAtIndex: index ++]) == NSNotFound)' –

+0

Значение 'location'' NSRange' '' NSNotFound', поэтому вам нужно что-то вроде 'aRange.location == NSNotFound' – CRD

 Смежные вопросы

  • Нет связанных вопросов^_^