【问题标题】:How to get the first N words from a NSString in Objective-C?如何从 Objective-C 中的 NSString 中获取前 N 个单词?
【发布时间】:2014-09-02 21:45:18
【问题描述】:

什么是最简单的方法,给定一个字符串:

NSString *str = @"Some really really long string is here and I just want the first 10 words, for example";

生成一个带有前 N 个(例如 10 个)单词的 NSString?

编辑:如果str 比 N 短,我还想确保它不会失败。

【问题讨论】:

    标签: objective-c string nsstring


    【解决方案1】:

    如果单词是空格分隔的:

    NSInteger nWords = 10;
    NSRange wordRange = NSMakeRange(0, nWords);
    NSArray *firstWords = [[str componentsSeparatedByString:@" "] subarrayWithRange:wordRange];
    

    如果你想打破所有的空白:

    NSCharacterSet *delimiterCharacterSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    NSArray *firstWords = [[str componentsSeparatedByCharactersInSet:delimiterCharacterSet] subarrayWithRange:wordRange];
    

    那么,

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

    【讨论】:

    • 你打败了我:+1。不要忘记 componentsJoinedByString: 因为 OP 正在寻找 NSString 结果:)
    • 如果字符串只有 3 个单词,这是否有效?什么是 wordIndexes? (在第一个示例中它似乎未使用)
    • 如果只有三个单词,您必须更改 nWords。当然,您可以在决定 nWords 之前找到 componentsSeparatedByString 并计算它们,但您没有在问题中提到这一点。
    • 现在作为一项要求提到 :) 因为这将对从 Web 服务加载的许多字符串执行。那么最简单的方法是使用某种 MIN 函数来设置 nWords?
    • 在我看来,您可以随心所欲地确定 nWords……它只是一个用于此处说明目的的变量。如果您决定 nWords 应该是检索到的以空格分隔的单词的某个百分比,而不是文字数字 10,那么只需将 [[str componentsSeparatedByString:@" "] count] 乘以该百分比。
    【解决方案2】:

    虽然 Barry Wark 的代码适用于英语,但它并不是检测断词的首选方法。许多语言(例如中文和日文)不使用空格分隔单词。例如,德语有许多难以正确分离的化合物。

    你要使用的是CFStringTokenizer:

    CFStringRef string; // Get string from somewhere
    CFLocaleRef locale = CFLocaleCopyCurrent();
    
    CFStringTokenizerRef tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault, string, CFRangeMake(0, CFStringGetLength(string)), kCFStringTokenizerUnitWord, locale);
    
    CFStringTokenizerTokenType tokenType = kCFStringTokenizerTokenNone;
    unsigned tokensFound = 0, desiredTokens = 10; // or the desired number of tokens
    
    while(kCFStringTokenizerTokenNone != (tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)) && tokensFound < desiredTokens) {
      CFRange tokenRange = CFStringTokenizerGetCurrentTokenRange(tokenizer);
      CFStringRef tokenValue = CFStringCreateWithSubstring(kCFAllocatorDefault, string, tokenRange);
    
      // Do something with the token
      CFShow(tokenValue);
    
      CFRelease(tokenValue);
    
      ++tokensFound;
    }
    
    // Clean up
    CFRelease(tokenizer);
    CFRelease(locale);
    

    【讨论】:

    • @sbooth 如果我的字符串以 @ 开头怎么办......让我们说这样的评论:@sbooth how are you。如何使用分词器查找 ["@sbooth"、"how"、"are"、"you"] 之类的内容?
    • @Georg 我不相信CFStringTokenizer 本身支持这种标记化类型。对于用户名检测之类的事情,您可以检查返回的用户名说明符 (@) 的令牌并将其附加到随后的令牌中。或者,如果您的用户名允许字符集定义明确,您可以使用正则表达式。
    【解决方案3】:

    根据 Barry 的回答,我为此页面编写了一个函数(仍然在 SO 上给予他功劳)

    + (NSString*)firstWords:(NSString*)theStr howMany:(NSInteger)maxWords {
    
        NSArray *theWords = [theStr componentsSeparatedByString:@" "];
        if ([theWords count] < maxWords) {
            maxWords = [theWords count];
        }
        NSRange wordRange = NSMakeRange(0, maxWords - 1);
        NSArray *firstWords = [theWords subarrayWithRange:wordRange];       
        return [firstWords componentsJoinedByString:@" "];
    }
    

    【讨论】:

      【解决方案4】:

      这是我的解决方案,源自此处给出的答案,用于我自己从字符串中删除第一个单词的问题...

      NSMutableArray *words = [NSMutableArray arrayWithArray:[lowerString componentsSeparatedByString:@" "]];
      [words removeObjectAtIndex:0];
      return [words componentsJoinedByString:@" "];
      

      【讨论】:

        猜你喜欢
        • 2013-02-28
        • 1970-01-01
        • 2013-04-10
        • 2011-04-19
        • 1970-01-01
        • 2014-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多