2009-11-18 3 views
9

Что это самый простой способ, учитывая строка:Как получить первые N слов из NSString в Objective-C?

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

, чтобы привести к NSString с первыми N (например, 10) слов?

EDIT: Я хотел бы также, чтобы убедиться, что он не подведет, если str короче, чем N.

ответ

30

Если слова через пробел:

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:@" "]; 
+0

Ты избил меня до этого: +1. Не забывайте о компонентахJoinedByString: поскольку OP искал результат NSString :) –

+0

Это работает, если строка содержит только 3 слова? Что такое wordIndexes? (он не используется в первом примере) – philfreo

+0

Вам нужно будет изменить nWords, если есть только три слова. Вы могли бы, конечно, найти компонентыSeparatedByString и посчитать их, прежде чем принимать решение о nWords, но вы не упомянули об этом в качестве требования в своем вопросе. –

32

В то время как код Барри Уорка хорошо работает для английского языка, это не лучший способ обнаружить разрывы слов. Многие языки, такие как китайский и японский, не разделяют слова, используя пробелы. У немецкого языка, например, есть много соединений, которые трудно отделить.

То, что вы хотите использовать 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); 
+1

Да, хорошо! Я должен думать за пределами моей локали. –

+0

Благодарим вас за хороший пример! – pnmn

+0

@sbooth Что делать, если моя строка начинается с @ ... скажем, как этот комментарий: '@sbooth, как вы'. Как я могу использовать токенизатор, чтобы найти что-то вроде ["@sbooth", "how", "are", "you"]? – Georg

7

На основании ответа Барри, я написал функцию для этой страницы (по-прежнему дает ему кредит на 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:@" "]; 
} 
2

Вот мое решение, полученное из ответов, приведенных здесь, для моей собственной проблемы удаления первого слова из строки ...

NSMutableArray *words = [NSMutableArray arrayWithArray:[lowerString componentsSeparatedByString:@" "]]; 
[words removeObjectAtIndex:0]; 
return [words componentsJoinedByString:@" "]; 
Смежные вопросы