Pertanyaan Ekstrak substring kata dari NSString pada indeks yang diberikan


Saya ingin menarik substring dari NSString pada indeks tertentu. Contoh:

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

Titik indeks '9' berada di tengah kata 'selamat datang', dan saya ingin dapat mengekstrak kata 'selamat datang' sebagai substring. Adakah yang bisa mengatakan kepada saya bagaimana saya akan mencapai ini? Dengan regex?


5
2018-03-13 16:35


asal


Jawaban:


Berikut ini solusi sebagai kategori di 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;
}

Dan lainnya, yang lebih rumit tetapi memungkinkan Anda menentukan dengan tepat karakter kata yang Anda inginkan:

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

Versi kedua juga lebih efisien dengan string panjang, dengan asumsi kata-kata itu pendek.


9
2018-03-13 17:01



Ini adalah cara yang agak bersifat peretas untuk melakukannya, tetapi itu akan berhasil:

NSString memiliki metode:

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

jadi Anda bisa melakukannya:

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

1
2018-03-13 16:59