2009-02-27 10 views
15

Ho appena letto il numero docu di Apple di NSScanner. Sto cercando di ottenere il numero intero di quella stringa: @ "utente registrato (3 tentativi)".Come usare NSScanner?

Non riesco a trovare alcun esempio, come scansionare tra parentesi. Qualche idea?

Ecco il codice:

NSString *logString = @"user logged (3 attempts)"; 
NSScanner *aScanner = [NSScanner scannerWithString:logString]; 

[aScanner scanInteger:anInteger]; 

NSLog(@"Attempts: %i", anInteger); 

risposta

16

`Qui è quello che faccio per ottenere determinati valori da una stringa di

Prima devo questo metodo definito

- (NSString *)getDataBetweenFromString:(NSString *)data leftString:(NSString *)leftData rightString:(NSString *)rightData leftOffset:(NSInteger)leftPos; 
{   
    NSInteger left, right;   
    NSString *foundData; 
    NSScanner *scanner=[NSScanner scannerWithString:data];     
    [scanner scanUpToString:leftData intoString: nil];   
    left = [scanner scanLocation];   
    [scanner setScanLocation:left + leftPos];   
    [scanner scanUpToString:rightData intoString: nil];   
    right = [scanner scanLocation] + 1;   
    left += leftPos;   
    foundData = [data substringWithRange: NSMakeRange(left, (right - left) - 1)];   return foundData; 
} 

Poi chiamarlo.

foundData = [self getDataBetweenFromString:data leftString:@"user logged (" rightString:@"attempts)" leftOffset:13]; 

leftOffset è il numero di caratteri per la stringa sinistra

Potrebbe essere un modo più semplice più pulite, ma che era la mia soluzione.

+1

non è necessario il leftPos. Questo può essere trovato usando la chiamata [leftData length]. Tuttavia questo è ottimo per acquisire dati tra stringhe dinamicamente. +1 – KronoS

+0

@Kalle: 'NULL' e' nil' sono definiti esattamente uguali, ma hanno un significato diverso. In questo caso, 'nil' è quello corretto. http://stackoverflow.com/questions/1841983/what-describes-nil-best-whats-that-really/1843034#1843034 –

+0

Grazie per quello - ho cancellato il commento in questione. Sì, NULL e nil sono identici. – Kalle

5

NSScanner è uno scanner lineare. Devi esaminare le cose che non vuoi arrivare a quello che vuoi.

Si potrebbe fare [aScanner scanUpToCharactersInSet:[NSCharacterSet decimalDigitCharacterSet] intoString:NULL] per saltare tutto fino al carattere numero. Quindi fai [aScanner scanInteger:&anInteger] per scansionare il personaggio in un numero intero.

50

La soluzione di Ziltoid funziona, ma è più un codice di cui hai bisogno.

Non mi preoccuperei di istanziare un NSScanner per la situazione data. NSCharacterSet e NSString voi tutti danno il necessario:

NSString *logString = @"user logged (3 attempts)"; 
    NSString *digits = [logString stringByTrimmingCharactersInSet: 
     [[NSCharacterSet decimalDigitCharacterSet] invertedSet]]; 
    NSLog(@"Attempts: %i", [digits intValue]); 

o in Swift: (yes, @NSResponder ha una soluzione veramente pulito)

let logString = "user logged (3 attempts)" 
    let nonDigits = NSCharacterSet.decimalDigitCharacterSet().invertedSet 
    let digits : NSString = logString.stringByTrimmingCharactersInSet(nonDigits) 
    NSLog("Attempts: %i", digits.intValue) 
+3

'invertedSet' nice! Non ero a conoscenza di quel metodo. Non riesco a ricordare come ho risolto questo problema prima, ma sicuramente non era elegante come questo. – kubi

5

Ecco una soluzione semplice utilizzando NSScanner:

uscita
NSString *logString = @"user logged (3 attempts)"; 
NSString *numberString; 
NSScanner *scanner = [NSScanner scannerWithString:logString]; 
[scanner scanUpToCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] intoString:nil]; 
[scanner scanCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] intoString:&numberString]; 
NSLog(@"Attempts: %i", [numberString intValue]); 

NSLog:

Attempts: 3 
1

ecco l'uso reg-ex

NSString *logString = @"user logged (3 attempts)"; 
NSString * digits = [logString stringByMatching:@"([+\\-]?[0-9]+)" capture:1];