19

I've just read Apple documentation for NSScanner. I'm trying to get the integer of this string:

@"user logged (3 attempts)" 

I can't find any example, how to scan within parentheses. Any ideas?

Here's the code:

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

5 Answers 5

53

Ziltoid's solution works, but it's more code than you need.

I wouldn't bother instantiating an NSScanner for the given situation. NSCharacterSet and NSString give you all you need:

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

or in Swift:

 let logString = "user logged (3 attempts)" let nonDigits = NSCharacterSet.decimalDigitCharacterSet().invertedSet let digits : NSString = logString.stringByTrimmingCharactersInSet(nonDigits) NSLog("Attempts: %i", digits.intValue) 
Sign up to request clarification or add additional context in comments.

1 Comment

invertedSet nice! I wasn't aware of that method. I can't remember how I solved this issue before, but it surely wasn't as elegant as this.
17

`Here is what I do to get certain values out of a string

First I have this method defined

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

Then call it.

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

leftOffset is the number of characters for the left string

Could be an easier cleaner way but that was my solution.

3 Comments

you don't need the leftPos. This can be found by using the [leftData length] call. However this is great for capturing data between strings dynamically. +1
@Kalle: NULL and nil are defined exactly the same, but have different meaning. In this case nil is the correct one. stackoverflow.com/questions/1841983/…
Thanks for that -- I deleted the comment in question. Yes, NULL and nil are identical.
7

Here is a simple solution using NSScanner (yes, @NSResponder has a really neat solution!):

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 output:

Attempts: 3 

Comments

5

NSScanner is a linear scanner. You have to scan through the stuff you don't want to get to what you do want.

You could do [aScanner scanUpToCharactersInSet:[NSCharacterSet decimalDigitCharacterSet] intoString:NULL] to jump past everything up to the number character. Then you do [aScanner scanInteger:&anInteger] to scan the character into an integer.

Comments

1

here is the reg-ex usage

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.