objective-c string cocoa parsing nsscanner

objective c - ¿Cómo usar NSScanner?



objective-c string (5)

Acabo de leer el docu de Apple de NSScanner. Estoy intentando obtener el entero de esa cadena: @ "usuario registrado (3 intentos)".

No puedo encontrar ningún ejemplo, cómo escanear entre paréntesis. ¿Algunas ideas?

Aquí está el código:

NSString *logString = @"user logged (3 attempts)"; NSScanner *aScanner = [NSScanner scannerWithString:logString]; [aScanner scanInteger:anInteger]; NSLog(@"Attempts: %i", anInteger);


Aquí está el uso reg-ex

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


Aquí hay una solución simple que usa NSScanner (sí, @NSResponder tiene una solución realmente ingeniosa):

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

Salida NSLog:

Attempts: 3


La solución de Ziltoid funciona, pero es más código del que necesita.

No me molestaría en crear una instancia de NSScanner para la situación dada. NSCharacterSet y NSString le ofrecen todo lo que necesita:

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

o en Swift:

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


`Esto es lo que hago para obtener ciertos valores de una cadena

Primero tengo definido este método.

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

Entonces llámalo.

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

leftOffset es el número de caracteres para la cadena izquierda

Podría ser una forma más fácil de limpiar pero esa fue mi solución.


NSScanner es un escáner lineal. Tienes que escanear a través de las cosas que no quieres llegar a lo que quieres.

Podría hacer [aScanner scanUpToCharactersInSet:[NSCharacterSet decimalDigitCharacterSet] intoString:NULL] para saltar más allá del carácter del número. Luego haces [aScanner scanInteger:&anInteger] para escanear el carácter en un entero.