views:

467

answers:

5

I have got below value(dynamic) from the server:

drwxr-xr-x    9 0        0            4096 Jan 10 05:30 California

Now i want to get valu like this.

drwxr-xr-x
9
0
0
4096
Jan 10
05:30 
California

Please help me for this question

+1  A: 

See NSString componentsSeparatedByString for your answer.

Alex Brown
+2  A: 

you can try smth like this

NSArray* components = [initialString componentsSeparatedByString:@" "];

Morion
Won't that split between "Jan" and "10" as well?
Sakkle
It will, but how can you handle this case generic way? seems its much easier to combine components afterwards if needed
Vladimir
+1  A: 
[myStringValue componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

may be useful as well.

Vladimir
+1  A: 

As others have mentioned, you can use NSString's member function componentsSeparatedByString: or componentsSeparatedByCharactersInSet:

As an alternative (for more powerful tokenizing), look into the Objective-C NSScanner class in the foundation framework of Mac OS X.

You could do something like this:

NSString *str = "drwxr-xr-x    9 0  ... ";
NSScanner *scanner = [NSScanner scannerWithString:str];

In order to obtain each token in string form, use NSScanner's scanUpToCharactersFromSet:intoString: member function.

NSString *token = [NSString string];
NSCharacterSet *div = [NSCharacterSet whitespaceCharacterSet];
[scanner scanUpToCharactersFromSet:div intoString:token];
// token now contains @"drwxr-xr-x"

Subsequent calls to the above would return 9, 0, and so on.

Note: the code above has not been tested.

ali01
+1  A: 

Use a regex: RegexKitLite.

This is a "complete example" of a way to use a regex to do what you want with a lot of explanation, so it's a bit of a long answer. The regex used is just one way to do this, and is "fairly permissive" in what it accepts. The example shows:

  • How to match more than "one line / directory" at once.
  • A possible way to handle different date formats (Jan 10 05:30 and Apr 30 2009)
  • How to create an "array of arrays" of matches.
  • Iterate over the matched array and create a NSDictionary based on the parsed results.
  • Create a "comma separated values" version of the results.

Note: The example splits up some of its long strings across multiple lines. A string literal in the form of @"string1 " @"string2" will be "automagically" concatenated by the compiler to form a string that is equivalent to @"string 1 string2". I note this only because this might look a bit unusual if you're not used to it.

#import <Foundation/Foundation.h>
#import "RegexKitLite.h"

int main(int argc, char *argv[]) {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  NSString *stringToMatch = 
    @"drwxr-xr-x    9 0        0            4096 Jan 10 05:30 California\n"
    @"-rw-r--r--    1 johne  staff     1335 Apr 30  2009 tags.m"; // A random entry from my machine with an "older" date.

  NSString *regex =
    @"(?m)^" // (?m) means: to "have ^ and $ match new line boundaries".  ^ means: "Match the start of a line".
    // Below, 
    // (...) means: "Capture for extraction the matched characters".  Captures start at 1, capture 0 matches "everything the regex matched".
    // [^\\p{Z}]+ says: "Match one or more characters that are NOT 'Separator' characters (as defined by Unicode, essentially white-space)".
    // In essence, '[^\\p{Z}]+' matches "One or more non-white space characters."
    // \\s+ says: Match one or more white space characters.
    // ([^\\p{Z}]+)\\s+ means: Match, and capture, the non-white space characters, then "gobble up" the white-space characters after the match.
    @"([^\\p{Z}]+)\\s+" // Capture 1 - Permission
    @"([^\\p{Z}]+)\\s+" // Capture 2 - Links (per `man ls`)
    @"([^\\p{Z}]+)\\s+" // Capture 3 - User
    @"([^\\p{Z}]+)\\s+" // Capture 4 - Group
    @"([^\\p{Z}]+)\\s+" // Capture 5 - Size
    @"(\\w{1,3}\\s+\\d+\\s+(?:\\d+:\\d+|\\d+))\\s+" // Capture 6 - The "date" part.
    // \\w{1,3} means: One to three "word-like" characters (ie, Jan, Sep, etc).
    // \\d+ means: Match one or more "digit-like" characters.
    // (?:...) means: Group the following, but don't capture the results.
    // (?:.A.|.B.) (the '|') means: Match either A, or match B.
    // (?:\\d+:\\d+|\\d+) means: Match either '05:30' or '2009'.
    @"(.*)$"; // Capture 7 - Name. .* means: "Match zero or more of any character (except newlines).  $ means: Match the end of the line.

  // Use RegexKitLites -arrayOfCaptureComponentsMatchedByRegex to create an
  // "array of arrays" composed of:
  // an array of every match of the regex in stringToMatch, and for each match,
  // an array of all the captures specified in the regex.

  NSArray *allMatchesArray = [stringToMatch arrayOfCaptureComponentsMatchedByRegex:regex];

  NSLog(@"allMatchesArray: %@", allMatchesArray);

  // Here, we iterate over the "array of array" and create a NSDictionary
  // from the results.

  for(NSArray *lineArray in allMatchesArray) {
    NSDictionary *parsedDictionary =
      [NSDictionary dictionaryWithObjectsAndKeys:
      [lineArray objectAtIndex:1], @"permission",
      [lineArray objectAtIndex:2], @"links",
      [lineArray objectAtIndex:3], @"user",
      [lineArray objectAtIndex:4], @"group",
      [lineArray objectAtIndex:5], @"size",
      [lineArray objectAtIndex:6], @"date",
      [lineArray objectAtIndex:7], @"name",
      NULL];
    NSLog(@"parsedDictionary: %@", parsedDictionary);
  }

  // Here, we use RegexKitLites -stringByReplacingOccurrencesOfRegex method to
  // create a new string. We use it to essentially transform the original string
  // in to a "comma separated values" version of the string.
  // In the withString: argument, '$NUMBER' means: "The characters that were matched
  // by capture group NUMBER."

  NSString *commaSeparatedString = [stringToMatch stringByReplacingOccurrencesOfRegex:regex withString:@"$1,$2,$3,$4,$5,$6,$7"];
  NSLog(@"commaSeparatedString:\n%@", commaSeparatedString);

  [pool release];
  pool = NULL;
  return(0);
}

Compile and run with:

shell% gcc -Wall -Wmost -arch i386 -g -o regexExample regexExample.m RegexKitLite.m -framework Foundation -licucore
shell% ./regexExample
2010-01-14 00:10:38.868 regexExample[49409:903] allMatchesArray: (
        (
        "drwxr-xr-x    9 0        0            4096 Jan 10 05:30 California",
        "drwxr-xr-x",
        9,
        0,
        0,
        4096,
        "Jan 10 05:30",
        California
    ),
        (
        "-rw-r--r--    1 johne  staff     1335 Apr 30  2009 tags.m",
        "-rw-r--r--",
        1,
        johne,
        staff,
        1335,
        "Apr 30  2009",
        "tags.m"
    )
)
2010-01-14 00:10:38.872 regexExample[49409:903] parsedDictionary: {
    date = "Jan 10 05:30";
    group = 0;
    links = 9;
    name = California;
    permission = "drwxr-xr-x";
    size = 4096;
    user = 0;
}
2010-01-14 00:10:38.873 regexExample[49409:903] parsedDictionary: {
    date = "Apr 30  2009";
    group = staff;
    links = 1;
    name = "tags.m";
    permission = "-rw-r--r--";
    size = 1335;
    user = johne;
}
2010-01-14 00:10:38.873 regexExample[49409:903] commaSeparatedString:
drwxr-xr-x,9,0,0,4096,Jan 10 05:30,California
-rw-r--r--,1,johne,staff,1335,Apr 30  2009,tags.m
johne