Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract word substring from NSString at given index

I want to pull out a substring from an NSString at a given index. Example:

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

Index point '9' is in the middle of the word 'welcome', and I would like to be able to extract that word 'welcome' as a substring. Can anyone tell me how I would achieve this? With a regex?

like image 258
mootymoots Avatar asked Mar 13 '13 16:03

mootymoots


People also ask

How do you extract a specific word from a string in Excel?

Depending on where you want to start extraction, use one of these formulas: LEFT function - to extract a substring from the left. RIGHT function - to extract text from the right. MID function - to extract a substring from the middle of a text string, starting at the point you specify.

How do I extract text before and after a specific character in Excel?

Extract text before or after space with formula in Excel Select a blank cell, and type this formula =LEFT(A1,(FIND(" ",A1,1)-1)) (A1 is the first cell of the list you want to extract text) , and press Enter button.

How can you extract a substring from a given string in Python?

You can extract a substring in the range start <= x < stop with [start:step] . If start is omitted, the range is from the beginning, and if end is omitted, the range is to the end. You can also use negative values. If start > end , no error is raised and an empty character '' is extracted.

How do I find a particular substring in a string?

You can extract a substring from a String using the substring() method of the String class to this method you need to pass the start and end indexes of the required substring.


2 Answers

Here's a solution as a category on 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;
}

And another, which is more complicated but lets you specify exactly the word characters you want:

- (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];
}

The second version is also more efficient with long strings, assuming the words are short.

like image 88
paulmelnikow Avatar answered Sep 22 '22 23:09

paulmelnikow


Here is a rather hackish way to do it, but it would work:

NSString has a method:

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

so you could do:

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;
}
like image 38
George Mitchell Avatar answered Sep 25 '22 23:09

George Mitchell