Search code examples
xcodensscanner

NSScanner scan after equal sign


oauth_token=requestkey&oauth_token_secret=requestsecret

How can I use NSScanner to get "requestkey" and "requestsecret". I can't seem to achieve it.

NSScanner* scanner = [NSScanner scannerWithString:string];
NSString *oauth_token = @"oauth_token=";
NSString *oauth_token_secret = @"oauth_token_secret=";
[scanner setCharactersToBeSkipped:nil];

NSString *token;
NSString *key;


while (![scanner isAtEnd]) {
    [scanner scanString:oauth_token intoString:NULL];
    [scanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"&"] intoString:&token];
    [scanner scanUpToString:oauth_token_secret intoString:NULL];
    [scanner scanUpToString:oauth_token intoString:&key];

    NSLog(@"token%@", token);
    NSLog(@"key %@", key);

//token requestkey
//key oauth_token_secret=requestsecret

}

I can't seem to figure out why is it null. Thanks!


Solution

  • Nothing is null. So I can't speak to that.

    It's actually a pretty straight forward error if you just follow the logic of your code line by line. For example:

    [scanner scanString:oauth_token intoString:nil];
    // The cursor is now just after the equals sign.
    [scanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"&"] intoString:&token];
    // This leaves the cursor just BEFORE the &.
    [scanner scanUpToString:oauth_token_secret intoString:nil];
    // This leaves the cursor just BEFORE the "oauth_token_secret="
    [scanner scanUpToString:oauth_token intoString:&key];
    // This scans effectively the rest of the string into &key which is in fact
    // "oauth_token_secret=requestsecret"
    

    The simplest way to fix this is to use the scanString:intoString: method to advance the cursor to the end of oauth_token_secret.

    [scanner scanString:oauth_token intoString:nil];
    [scanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"&"] intoString:&token];
    [scanner scanUpToString:oauth_token_secret intoString:nil];
    // This leaves the cursor just BEFORE the "oauth_token_secret="
    
    // **FIX HERE**
    [scanner scanString:oauth_token_secret intoString:nil];
    // The cursor is now AFTER oauth_token_secret.
    
    [scanner scanUpToString:oauth_token intoString:&key];
    

    The log output now shows useful strings.

    token:requestkey
    key  :requestsecret
    

    But, as H2CO3 said in the comments section, componentsSeparatedByString: is a much better fit for this use case.