Count The Number of Words in an NSString

Here’s a quick way to count the number of words in an NSString object. The trick is to use the character set whitespaceAndNewlineCharacterSet which will look for spaces, tabs and newline characters.

- (NSUInteger)wordCount:(NSString *)str 
{
  NSUInteger words = 0;
 
  NSScanner *scanner = [NSScanner scannerWithString: str];
 
  // Look for spaces, tabs and newlines
  NSCharacterSet *whiteSpace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
  while ([scanner scanUpToCharactersFromSet:whiteSpace  intoString:nil])
    words++;
 
  return words;
}

If you have another way to reach the same result, please post a code sample.

11 Comments

  1. Maybe a more elegant approach is to use NSLinguisticTagger:

    NSString *linguisticTaggerTestString = @”Do any additional setup after loading the view, typically from a nib.”;

    NSLinguisticTagger *lingusticTagger = [[NSLinguisticTagger alloc] initWithTagSchemes:[NSArray arrayWithObject:NSLinguisticTagSchemeTokenType] options:0];
    [lingusticTagger setString:linguisticTaggerTestString];

    [lingusticTagger enumerateTagsInRange:NSMakeRange(0, [linguisticTaggerTestString length])
    scheme:NSLinguisticTagSchemeTokenType
    options:0 usingBlock:^(NSString *tag, NSRange tokenRange, NSRange sentenceRange, BOOL *stop)
    {
    NSLog(@”%@ (%@)”, [linguisticTaggerTestString substringWithRange:tokenRange], tag);
    }];

    • You need to use

      if ([tag isEqualTo: NSLinguisticTagWord]) { NSLog(…); }

      in your block for that to get a sensible result, but then it works.

  2. I usally just use the following

    return [[message componentsSeparatedByString:@” “] count];

  3. NSString *str = “some text with new line\nfew spaces and something like non regular punctuation… text me :)”
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@”\\w+\\s*” options:NSRegularExpressionCaseInsensitive error:nil];
    NSUInteger numberOfMatches = [regex numberOfMatchesInString:str
    options:0
    range:NSMakeRange(0, [str length])];
    NSLog(@”%d words”, numberOfMatches);

  4. How about this :

    – (NSUInteger)wordCount:(NSString *)str
    {
    return [str componentsSeparatedByCharactersInSet:
    [NSCharacterSet whitespaceAndNewlineCharacterSet]
    count];
    }

  5. Yes i have :)

    you can use – (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator

    – (NSUInteger)anotherWordCount
    {
    NSString *mystring = @”Think different! Steve Jobs, Apple Inc.”;
    NSCharacterSet *whiteSpace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    NSArray *result = [mystring componentsSeparatedByCharactersInSet:whiteSpace];
    return result.count;
    }

    Maybe it’s more fast than a NSSCanner but it uses more memory (for the NSArray creation).

    Good Luck :)

  6. You could use a regular expression, like:

    NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@”\\w+” options:0 error:nil];
    if (!regex && error) {
    NSLog(@”better do more than just call NSLog in production code!”);
    }
    NSUInteger words = [regex numberOfMatchesInString:str options:0 range:NSMakeRange(0, [str length])];

    The regex approach would do better if you wanted to ignore, e.g. stand-alone punctuation, and if you cache the regex (maybe in the thread dictionary) it *may* get better performance.

  7. Why so complicated, everyone?

    NSString *wordString = @”long string with lots of words”;
    [wordString enumerateSubstringsInRange:NSMakeRange(0, wordString.length) options:NSStringEnumerationByWords usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
    NSLog(@”Word:%@”, substring);
    //Profit
    }];

  8. NSArray *sampleArray= [str componentsSeparatedByString:@” “];

    [sampleArray count];

Comments are closed.