Anthony Main
Anthony Main

Reputation: 6068

How do I use NSScanner to parse a tab delimited string in Cocoa?

I have a web service which returns tab delimited data (see sample below).

I need to parse this into an array or similar so I can create a navigation view of it.

I've managed to perform the web request and could parse an XML file, but my knowledge of Objective-C is small.

433 Eat
    502 Not Fussed
    442 British
    443 Chinese
    444 Dim Sum
    445 Fish
    446 French
    447 Gastropubs
    449 Indian
    451 Italian
    452 Japanese
    453 Middle Eastern
    454 Pan-Asian
    455 Pizza
    456 Spanish
    457 Tapas
    458 Thai
    459 Vegetarian
434 Drink
    501 Not Fussed
    460 Bars 
    461 Pubs

Upvotes: 0

Views: 9061

Answers (3)

Brett
Brett

Reputation: 2809

I'm not sure I understand your format exactly (it displays a little strange to me) but the easiest way to do this is with - (NSArray *)componentsSeparatedByString:(NSString *)separator which is a method in the NSString class... example:

NSArray *components = [myString componentsSeperatedByString:@"\t"];

This returns an NSArray of NSStrings, one for each tab-delimited field. If the new-line separators are important you can use - (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator (also on NSString) to split using more than one kind of delimiter.

Upvotes: 8

Peter Hosey
Peter Hosey

Reputation: 96373

You're on the right track with NSScanner. You'll need at least two scanners: One to scan lines from the whole input string, and one scanner for each line. Set the whole-input scanner to skip only whitespace (not newlines), then:

  1. Scan one line (source string up to end-of-line).
  2. Create a scanner and have it scan tabs from the line.
  3. Count the tabs you scanned. That's your indentation level.
  4. The rest of the line is the entry number and name. You could scan the line up to whitespace to separate the number and name, or leave them together, depending on what you need.
  5. Go back to step 1.

For specific method names, see the NSScanner class reference and the NSCharacterSet class reference.

Upvotes: 2

Brett
Brett

Reputation: 2809

I had a feeling more than a flat list is wanted. If you want a multidimensional structure you can do something like this:

NSArray *lines = [data componentsSeparatedByString:@"\n"];
for (NSString *line in lines) {
    NSArray *fields = [line componentsSeparatedByString:@"\t"];
     // Do something here with each two-element array, such as add to an NSDictionary or to an NSArray (to make a multidimensional array.)
}

Upvotes: 4

Related Questions