Ajay Venkat
Ajay Venkat

Reputation: 9

Split an NSString at the first capital letter

I have a string like this @"abcdefghijklmnopqrstuvwxyzA". As you can see, A is at the end. How can I find the first capital letter and split the strings:

NSString *lower = @"abcdefghijklmnopqrstuvwxyz";
NSString *upper = @"A";

The string in the beginning is static so the capital letter could be ANYTHING. Will this scanner help?

NSString *String = titleLabelLatestNews.text;

NSScanner *stringScanner = [NSScanner scannerWithString:String];    
NSString *content = [[NSString alloc] init];

while ([stringScanner isAtEnd] == NO) {

    [stringScanner scanUpToString:@"url=\"" intoString:Nil];

    [stringScanner scanUpToString:@"/>" intoString:&content];
}

For another example, @"this is all lower case letters I am awesome"; should become two strings, @"this is all lower case letters"; and @"I am awesome";

Get the idea? Anything before the Capital Letter goes to a string and anything after goes to another string.

Upvotes: 0

Views: 1246

Answers (6)

Paulw11
Paulw11

Reputation: 114975

A better solution is to use NSString's rangeOfCharacterFromSet

 NSString *lowerCaseString=@"";
 NSString *upperCaseString=@"";
 NSString *stringToSplit = titleLabelLatestNews.text;
 NSRange capitalRange=[stringToSplit rangeOfCharacterFromSet:[NSCharacterSet uppercaseLetterCharacterSet]];
 if (capitalRange.location == NSNotFound) {
    lowerCaseString=stringToSplit;
 }
 else if (capitalRange.location ==0 ) {
    upperCaseString=stringToSplit;
 }
 else {
    lowerCaseString=[stringToSplit substringToIndex:capitalRange.location-1];
    upperCaseString=[stringToSplit substringFromIndex:capitalRange.location];
 }

 NSLog(@"lower case string=%@ uppercase=%@",lowerCaseString,upperCaseString);

Upvotes: 1

Lyndsey Scott
Lyndsey Scott

Reputation: 37300

Throwing one more solution into the mix utilizing componentsSeparatedByCharactersInSet: to split the string into multiple arrays (i.e. more than 2 if needed):

// Separate the "sentence" into components separated
// by the characters in the uppercase character set
NSMutableArray *sentenceArray = [[sentence componentsSeparatedByCharactersInSet:[NSCharacterSet uppercaseLetterCharacterSet]] mutableCopy];

// Get the first sentence "segment", i.e. the sentenceArray's
// first object
NSString *segment = [sentenceArray objectAtIndex:0];

// Keep track of the character count with a variable
int characterCount = (int)segment.length;

// Then starting from sentenceArray's index 1, go through
// the rest of sentenceArray's indices
for (int i = 1 ; i < sentenceArray.count ; i ++) {

    // Append that "separator" character to the segment at the
    // current index by accessing the character before the current segment
    segment = [[NSString stringWithFormat:@"%c", [sentence characterAtIndex:characterCount]]stringByAppendingString:[sentenceArray objectAtIndex:i]];

    // Replace the object at the current index with this new segment
    // string
    [sentenceArray replaceObjectAtIndex:i withObject:segment];

     // Increment the character count
    characterCount += segment.length;
}

NSLog(@"%@", sentenceArray);

Upvotes: 0

CRD
CRD

Reputation: 53010

For completeness, the regular expression solution:

  1. Use NSRegularExpression

  2. The pattern @"([^A-Z]*)([A-Z].*)" will match what you want if you are only interested in A-Z as uppercase characters (see below for unicode change). Broken down this is two group, (...), one for before one for after; first group - anything which is not uppercase, [^A-Z], zero or more times, *; second group - an uppercase letter, [A-Z], followed by anything, .*.

  3. Use firstMatchInString:options:range:; the NSTextCheckingResult will contain the ranges of the two matched groups.

If you wish to allow for Unicode's myriad of uppercase and titlecase letters just change A-Z above to \\p{Lu}\\p{Lt} (make sure you type the double-backslashes, you are passing a backslash to NSRegularExpression). Those two are all the Unicode uppercase letters, \\p{Lu}, and all the title case letters, \\p{Lt}.

HTH

Upvotes: 0

jscs
jscs

Reputation: 64002

An NSScanner will do the trick for you, yes. You just need to create an NSCharacterSet consisting of the capital letters, then use scanUpToCharactersFromSet:intoString:

NSString * s = @"this is all lower case letters I am awesome";
NSScanner * scanner = [NSScanner scannerWithString:s];
NSString * firstPart;
[scanner scanUpToCharactersFromSet:[NSCharacterSet uppercaseLetterCharacterSet]
                        intoString:&firstPart];
NSString * secondPart = [s substringFromIndex:[scanner scanLocation]];

Upvotes: 2

matt
matt

Reputation: 535586

If you insist on using NSScanner, use scanCharactersFromSet:intoString: where the NSCharacterSet is lowercase characters only.

What I would personally do, if anyone cares, is call rangeOfCharacterFromSet(NSCharacterSet.uppercaseLetterCharacterSet()...) and derive the resulting substrings from there.

Upvotes: 1

Khanh Nguyen
Khanh Nguyen

Reputation: 11132

// Find index of first capital letter
NSInteger index = ^NSInteger{
    for (NSInteger i = 0; i < string.length; ++i) {
        unichar c = [string characterAtIndex:i];
        if ('A' <= c && c <= 'Z') { return i; }
    }

    return string.length; // No capital letter, take the entire string
}();

NSLog(@"lower = %@", [string substringToIndex:index]);
NSLog(@"upper = %@", [string substringFromIndex:index]);

Upvotes: -1

Related Questions