Регулярное выражение, указывающее необязательные группы захвата? - PullRequest
2 голосов
/ 09 февраля 2012

Есть ли способ написать шаблон регулярного выражения, который создаст одну или две группы на основе входного текста. (То есть.)

// ONE
NSString *pattern = @""; ([0-9]+).([0-9]+)
NSString *inputText = @"ThisIs MyTest72.56String";
// OUTPUT match = 72.56, group1 = 72, group2 = 56

Что я пытаюсь получить:

// TWO
NSString *pattern = @""; ([0-9]+).([0-9]+)
NSString *inputText = @"ThisIs MyTest72String";
// OUTPUT match = 72, group1 = 72, group2 = Empty

Я думал, что смогу использовать (? :), но это просто удаляет группу

За чем я следую:

Text = "ThisIs MyTest72String"
Match = 72
Group1 = 72
Group2 = Empty

Text = "ThisIs MyTest72.56String"
Match = 72.56
Group1 = 72
Group2 = 56

EDIT:

Такого рода работы, хотя я бы хотел избавиться от "S" в начальном матче.

Pattern = ([0-9]+).([0-9]*)
Text = "ThisIs MyTest72String"
Match = 72S
Group1 = 72    //RangeAtIndex:1 {13,2}
Group2 = Empty //RangeAtIndex:2 {16,0}

Text = "ThisIs MyTest72.56String"
Match = 72.56
Group1 = 72
Group2 = 56

Это близко, но в случае «Пусто» (Group2) я ожидал, что rangeAtIndex: 2 равняется NSNotFound. В документах говорится «Диапазон {NSNotFound, 0} возвращается, если одна из групп захвата не участвовала в этом конкретном матче» Является ли группа пустой, не считается ли она «Не участвующей»?

Ответы [ 3 ]

1 голос
/ 09 февраля 2012

Используйте этот шаблон:

pattern = @"([0-9]+)\.([0-9]+)?";

, а затем в NSTextCheckingResult проверьте, является ли диапазон диапазона группы NSNotFound.

Пример кода:

NSString *pattern = @"([0-9]+).([0-9]+)?";
NSString *string = @"ThisIs MyTest72.56String";
//NSString *string = @"ThisIs MyTest72.XXString";

NSRegularExpression *regex = [NSRegularExpression
                              regularExpressionWithPattern:pattern
                              options:NSRegularExpressionCaseInsensitive
                              error:nil];

NSTextCheckingResult *match = [regex firstMatchInString:string options:0 range:NSMakeRange(0, string.length)];

for (int groupNumber=1; groupNumber<match.numberOfRanges; groupNumber+=1) {
    NSRange groupRange = [match rangeAtIndex:groupNumber];
    if (groupRange.location != NSNotFound)
        NSLog(@"match %d: '%@'", groupNumber, [string substringWithRange:groupRange]);
    else
        NSLog(@"match %d: '%@'", groupNumber, @"");
}

Вывод NSLog:

соответствует 1: '72'
матч 2: '56'
Со вторым шаблоном "match 2: ''".

1 голос
/ 09 февраля 2012

Как насчет этого:

NSString *inputText = @"ThisIs MyTest72.56String";
// Setup an NSError object to catch any failures
NSError *error = NULL;  
// create the NSRegularExpression object and initialize it with a pattern
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\d+.\\d+" options:NSRegularExpressionCaseInsensitive error:&error];
// create an NSRange object using our regex object for the first match in the string httpline
NSRange rangeOfFirstMatch = [regex rangeOfFirstMatchInString:inputText options:0 range:NSMakeRange(0, [inputText 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 = [inputText substringWithRange:rangeOfFirstMatch];
    NSLog(@"Extracted string: %@",substringForFirstMatch); // Extracted string: 72.56

regex = [NSRegularExpression regularExpressionWithPattern:@"\\d+" options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *matches = [regex matchesInString:substringForFirstMatch options:0 range:NSMakeRange(0, [substringForFirstMatch length])];
for (NSTextCheckingResult *match in matches) {
    NSString *matchString = [substringForFirstMatch substringWithRange:[match range]];
    NSLog(@"match string: %@", matchString);
    // match string: 72
    // match string: 56
}

}
1 голос
/ 09 февраля 2012

Дает ли это то, что вы хотите?

([0-9]+)(?:\.([0-9]+))?

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

Следует просто проверить наличие второй группы.

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