2012-10-26 16 views
5

Jestem dość zielony w regex z Objective-C. Mam z tym trudności.Objective-C NSRegularExpressions, znajdowanie pierwszego wystąpienia liczb w ciągu

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\b([1-9]+)\\b" options:NSRegularExpressionCaseInsensitive error:&regError]; 
if (regError) { 
    NSLog(@"%@",regError.localizedDescription); 
} 
__block NSString *foundModel = nil; 
[regex enumerateMatchesInString:self.model options:kNilOptions range:NSMakeRange(0, [self.model length]) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) { 
    foundModel = [self.model substringWithRange:[match rangeAtIndex:0]]; 
    *stop = YES; 
}]; 

Wszystko szukam zrobić, to wziąć ciąg jak

150A 

I dostać

150 

Odpowiedz

7

pierwszych problemy z regex:

  1. używasz granice słowa (\b) co oznacza, że ​​są tylko patrząc na numer, który jest sam w sobie (na przykład 15, ale nie 150a).
  2. Twój zakres numerów nie obejmuje 0, więc nie zostanie przechwycony 150. Musi to być [0-9]+ i jeszcze lepiej używać \d+.

Aby to naprawić, jeśli chcesz przechwycić dowolną liczbę, wszystko, czego potrzebujesz, to \d+. Jeśli chcesz uchwycić wszystko, co zaczyna się od cyfry, umieść granicę słowa tylko na początku \b\d+.

Teraz, aby uzyskać pierwsze wystąpienie można użyć
-[regex rangeOfFirstMatchInString:options:range:]

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\b\\d+" options:NSRegularExpressionCaseInsensitive error:&regError]; 
if (regError) { 
    NSLog(@"%@",regError.localizedDescription); 
} 

NSString *model = @"150A"; 
NSString *foundModel = nil; 
NSRange range = [regex rangeOfFirstMatchInString:model options:kNilOptions range:NSMakeRange(0, [model length])]; 
if(range.location != NSNotFound) 
{ 
    foundModel = [model substringWithRange:range]; 
} 

NSLog(@"Model: %@", foundModel); 
+0

Tak doskonały. Dziękuję Ci! – rnystrom

0

Co .*?(\d+).*??

Demo: To powoduje, że numeracja wsteczna będzie numerowana i będzie można z niego korzystać w dowolnym miejscu.

+0

Niestety, to nie działa jak '*' * robi * najdłuższy mecz, więc z wejściem '' 150A' pierwszy. * 'dopasowuje' 15', '(\ d +)' dopasowuje '0', a końcowe'. * 'dopasowuje' A'. – CRD

+0

Przepraszam, zapominam o znaku "leniwym" –

+0

Tak, * najkrótszy * mecz to zrobi, ale na pewno potrzebujesz tylko pierwszego? (I oczywiście są też inne re, które też to zrobią, jednak wzorzec taki jak @ Joe dopasowuje tylko wymaganą liczbę, która jest dobra). – CRD

Powiązane problemy