2013-03-13 68 views
5

我想從給定索引處的NSString中提取子字符串。例如:在給定索引處從NSString中提取字子字符串

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

指數點位「9」是一個詞「歡迎」的中間,我想是能夠提取詞「歡迎」作爲一個子字符串。任何人都可以告訴我怎麼做到這一點?用正則表達式?

+0

你想'e'還是'welcome'? – 2013-03-13 16:36:24

+0

我想單詞'welcome' – mootymoots 2013-03-13 16:37:27

+0

這個問題不是無效的嗎?爲什麼有人會用正則表達式或nsset去找?它可以很容易地用nsstring類的方法找到。 – 2013-03-13 16:52:32

回答

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

的第二個版本,也有長串更高效,假設話則短。

+0

所以這是很好的謝謝,雖然如果索引是在結束/開始字,它返回空我猜,因爲它不在範圍內。有什麼方法可以適應這種情況? – mootymoots 2013-03-13 17:14:07

+0

對不起,它確實有效 - 我的不好。但是,如果單詞以#或@開始,它不會註冊@或# - 因爲NSStringEnumerationByWords而錯過了嗎? – mootymoots 2013-03-13 17:27:54

+0

我做了一個編輯,將'NSLocationInRange(index,substringRange)'改爲'NSLocationInRange(index,enclosingRange)',即使你登陸字邊界,它也應該返回一個字。我會偷看@或#的情況 - 你會給我一個例子,並告訴我你想要什麼輸出? – paulmelnikow 2013-03-13 17:39:22

1

這裏是做一個相當hackish的方式,但它的工作:

的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; 
} 
+0

你解決了,好!但是根據OP,正則表達式在哪裏。 – 2013-03-13 17:00:38

+1

我很懶惰...我會爲那些比我更耐心的人留下。 – 2013-03-13 17:03:10

+0

不錯的一個:)喜歡你的幽默感 – 2013-03-13 17:32:28

相關問題