Collapse sequences of white space into a single character and trim string

Objective CIosNsstring

Objective C Problem Overview


Consider the following example:

"    Hello      this  is a   long       string!   "

I want to convert that to:

"Hello this is a long string!"

Objective C Solutions


Solution 1 - Objective C

OS X 10.7+ and iOS 3.2+

Use the native regexp solution provided by hfossli.

Otherwise

Either use your favorite regexp library or use the following Cocoa-native solution:

NSString *theString = @"    Hello      this  is a   long       string!   ";

NSCharacterSet *whitespaces = [NSCharacterSet whitespaceCharacterSet];
NSPredicate *noEmptyStrings = [NSPredicate predicateWithFormat:@"SELF != ''"];

NSArray *parts = [theString componentsSeparatedByCharactersInSet:whitespaces];
NSArray *filteredArray = [parts filteredArrayUsingPredicate:noEmptyStrings];
theString = [filteredArray componentsJoinedByString:@" "];

Solution 2 - Objective C

Regex and NSCharacterSet is here to help you. This solution trims leading and trailing whitespace as well as multiple whitespaces.

NSString *original = @"    Hello      this  is a   long       string!   ";

NSString *squashed = [original stringByReplacingOccurrencesOfString:@"[ ]+"
                                                         withString:@" "
                                                            options:NSRegularExpressionSearch
                                                              range:NSMakeRange(0, original.length)];

NSString *final = [squashed stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

Logging final gives

"Hello this is a long string!"

Possible alternative regex patterns:

  • Replace only space: [ ]+
  • Replace space and tabs: [ \\t]+
  • Replace space, tabs and newlines: \\s+

Performance rundown

Ease of extension, performance, number lines of code and the number of objects created makes this solution appropriate.

Solution 3 - Objective C

Actually, there's a very simple solution to that:

NSString *string = @" spaces in front and at the end ";
NSString *trimmedString = [string stringByTrimmingCharactersInSet:
                                  [NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(@"%@", trimmedString)

(Source)

Solution 4 - Objective C

With a regex, but without the need for any external framework:

NSString *theString = @"    Hello      this  is a   long       string!   ";

theString = [theString stringByReplacingOccurrencesOfString:@" +" withString:@" "
                       options:NSRegularExpressionSearch
                       range:NSMakeRange(0, theString.length)];

Solution 5 - Objective C

A one line solution:

NSString *whitespaceString = @" String with whitespaces ";

NSString *trimmedString = [whitespaceString
        stringByReplacingOccurrencesOfString:@" " withString:@""];

Solution 6 - Objective C

This should do it...

NSString *s = @"this is    a  string    with lots  of     white space";
NSArray *comps = [s componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

NSMutableArray *words = [NSMutableArray array];
for(NSString *comp in comps) {
  if([comp length] > 1)) {
    [words addObject:comp];
  }
}

NSString *result = [words componentsJoinedByString:@" "];

Solution 7 - Objective C

Another option for regex is RegexKitLite, which is very easy to embed in an iPhone project:

[theString stringByReplacingOccurencesOfRegex:@" +" withString:@" "];

Solution 8 - Objective C

Here's a snippet from an NSString extension, where "self" is the NSString instance. It can be used to collapse contiguous whitespace into a single space by passing in [NSCharacterSet whitespaceAndNewlineCharacterSet] and ' ' to the two arguments.

- (NSString *) stringCollapsingCharacterSet: (NSCharacterSet *) characterSet toCharacter: (unichar) ch {
int fullLength = [self length];
int length = 0;
unichar *newString = malloc(sizeof(unichar) * (fullLength + 1));

BOOL isInCharset = NO;
for (int i = 0; i < fullLength; i++) {
	unichar thisChar = [self characterAtIndex: i];
	
	if ([characterSet characterIsMember: thisChar]) {
		isInCharset = YES;
	}
	else {
		if (isInCharset) {
			newString[length++] = ch;
		}
		
		newString[length++] = thisChar;
		isInCharset = NO;
	}
}

newString[length] = '\0';

NSString *result = [NSString stringWithCharacters: newString length: length];

free(newString);

return result;
}

Solution 9 - Objective C

Try This

NSString *theString = @"    Hello      this  is a   long       string!   ";

while ([theString rangeOfString:@"  "].location != NSNotFound) {
    theString = [theString stringByReplacingOccurrencesOfString:@"  " withString:@" "];
}

Solution 10 - Objective C

Alternative solution: get yourself a copy of OgreKit (the Cocoa regular expressions library).

  • OgreKit (Japanese webpage -- code is in English)
  • OgreKit (Google autotranslation):

The whole function is then:

NSString *theStringTrimmed =
   [theString stringByTrimmingCharactersInSet:
        [NSCharacterSet whitespaceAndNewlineCharacterSet]];
OGRegularExpression  *regex =
    [OGRegularExpression regularExpressionWithString:@"\s+"];
return [regex replaceAllMatchesInString:theStringTrimmed withString:@" "]);

Short and sweet.

If you're after the fastest solution, a carefully constructed series of instructions using NSScanner would probably work best but that'd only be necessary if you plan to process huge (many megabytes) blocks of text.

Solution 11 - Objective C

according from @Mathieu Godart is best answer, but some line is missing , all answers just reduce space between words , but when if have tabs or have tab in place space , like this: " this is text \t , and\tTab between , so on " in three line code we will : the string we want reduce white spaces

NSString * str_aLine = @"    this is text \t , and\tTab between      , so on    ";
// replace tabs to space
str_aLine = [str_aLine stringByReplacingOccurrencesOfString:@"\t" withString:@" "];
// reduce spaces to one space
str_aLine = [str_aLine stringByReplacingOccurrencesOfString:@" +" withString:@" "
                                                    options:NSRegularExpressionSearch
                                                      range:NSMakeRange(0, str_aLine.length)];
// trim begin and end from white spaces
str_aLine = [str_aLine stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

the result is

"this is text , and Tab between , so on"

without replacing tab the resul will be:

"this is text 	 , and	Tab between , so on"

Solution 12 - Objective C

Following two regular expressions would work depending on the requirements

  1. @" +" for matching white spaces and tabs
  2. @"\\s{2,}" for matching white spaces, tabs and line breaks

Then apply nsstring's instance method stringByReplacingOccurrencesOfString:withString:options:range: to replace them with a single white space.

e.g.

[string stringByReplacingOccurrencesOfString:regex withString:@" " options:NSRegularExpressionSearch range:NSMakeRange(0, [string length])];

Note: I did not use 'RegexKitLite' library for the above functionality for iOS 5.x and above.

Solution 13 - Objective C

You can also use a simple while argument. There is no RegEx magic in there, so maybe it is easier to understand and alter in the future:

while([yourNSStringObject replaceOccurrencesOfString:@"  "
                         withString:@" "
                         options:0
                         range:NSMakeRange(0, [yourNSStringObject length])] > 0);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPaulView Question on Stackoverflow
Solution 1 - Objective CGeorg SchöllyView Answer on Stackoverflow
Solution 2 - Objective ChfossliView Answer on Stackoverflow
Solution 3 - Objective CarikfrView Answer on Stackoverflow
Solution 4 - Objective CMonsieurDartView Answer on Stackoverflow
Solution 5 - Objective CTwoBeerGuyView Answer on Stackoverflow
Solution 6 - Objective CBarry WarkView Answer on Stackoverflow
Solution 7 - Objective CDaniel DickisonView Answer on Stackoverflow
Solution 8 - Objective CdmercrediView Answer on Stackoverflow
Solution 9 - Objective Csinh99View Answer on Stackoverflow
Solution 10 - Objective CMatt GallagherView Answer on Stackoverflow
Solution 11 - Objective CKosarView Answer on Stackoverflow
Solution 12 - Objective CapalvaiView Answer on Stackoverflow
Solution 13 - Objective CSven-Steffen ArndtView Answer on Stackoverflow