在给定索引处从NSString中提取单词子串

时间:2013-03-13 16:35:11

标签: ios cocoa nsstring substring

我想从给定索引处的NSString中提取子字符串。例如:

NSString = @"Hello, welcome to the jungle";
int index = 9;

索引点'9'位于'welcome'一词的中间,我希望能够将'welcome'这个词作为子串提取出来。谁能告诉我如何实现这一目标?正则表达式?

2 个答案:

答案 0 :(得分:9)

这是NSString上的一个解决方案:

- (NSString *) wordAtIndex:(NSInteger) index {
    __block NSString *result = nil;
    [self enumerateSubstringsInRange:NSMakeRange(0, self.length)
                             options:NSStringEnumerationByWords
                          usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
                              if (NSLocationInRange(index, enclosingRange)) {
                                  result = substring;
                                  *stop = YES;
                              }
                          }];
    return result;
}

另一个,更复杂,但让你准确指定你想要的单词:

- (NSString *) wordAtIndex:(NSInteger) index {
    if (index < 0 || index >= self.length)
        [NSException raise:NSInvalidArgumentException
                    format:@"Index out of range"];

    // This definition considers all punctuation as word characters, but you
    // can define the set exactly how you like
    NSCharacterSet *wordCharacterSet =
    [[NSCharacterSet whitespaceAndNewlineCharacterSet] invertedSet];

    // 1. If [self characterAtIndex:index] is not a word character, find
    // the previous word. If there is no previous word, find the next word.
    // If there are no words at all, return nil.
    NSInteger adjustedIndex = index;
    while (adjustedIndex < self.length &&
           ![wordCharacterSet characterIsMember:
            [self characterAtIndex:adjustedIndex]])
        ++adjustedIndex;
    if (adjustedIndex == self.length) {
        do
            --adjustedIndex;
        while (adjustedIndex >= 0 &&
               ![wordCharacterSet characterIsMember:
                [self characterAtIndex:adjustedIndex]]);
        if (adjustedIndex == -1)
            return nil;
    }

    // 2. Starting at adjustedIndex which is a word character, find the
    // beginning and end of the word
    NSInteger beforeBeginning = adjustedIndex;
    while (beforeBeginning >= 0 &&
           [wordCharacterSet characterIsMember:
            [self characterAtIndex:beforeBeginning]])
        --beforeBeginning;

    NSInteger afterEnd = adjustedIndex;
    while (afterEnd < self.length &&
           [wordCharacterSet characterIsMember:
            [self characterAtIndex:afterEnd]])
        ++afterEnd;

    NSRange range = NSMakeRange(beforeBeginning + 1,
                                afterEnd - beforeBeginning - 1);
    return [self substringWithRange:range];
}

第二个版本对于长字符串也更有效,假设单词很短。

答案 1 :(得分:1)

这是一种相当神圣的做法,但它会起作用:

NSString有一个方法:

- (NSArray *)componentsSeparatedByString:(NSString *)separator;

所以你可以这样做:

NSString *myString = @"Blah blah blah";
NSString *output = @"";
int index = 9;
NSArray* myArray = [myString componentsSeparatedByString:@" "]; // <-- note the space in the parenthesis

for(NSString *str in myArray) {
    if(index > [str length]) index -= [str length] + 1; // don't forget the space that *was* there
    else output = str;
}