2013-03-13 8 views
5

Ich möchte eine Teilzeichenfolge aus einem NSString bei einem bestimmten Index ziehen. Beispiel:Extract Word Teilzeichenfolge aus NSString bei gegebenem Index

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

Index Punkt ‚9‘ ist in der Mitte des Wortes ‚Willkommen‘, und ich möchte in der Lage sein, dieses Wort zu extrahieren ‚Willkommen‘ als Teil. Kann mir jemand sagen, wie ich das erreichen würde? Mit einer Regex?

+0

wollen Sie "e" oder "Willkommen"? –

+0

Ich möchte das Wort "Willkommen" – mootymoots

+0

Ist diese Frage nicht gültig? Warum sollte jemand mit Regex oder Nsset suchen? Es kann mit den Klassenmethoden von NString ganz leicht gefunden werden. –

Antwort

9

Hier ist eine Lösung als eine Kategorie auf 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; 
} 

Und ein anderer, die komplizierter ist, aber können Sie genau die Wortzeichen geben Sie wollen:

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

Die zweite Version ist auch effizienter mit langen Strings, vorausgesetzt, die Worte kurz sind.

+0

so ist das gut danke, obwohl, wenn der Index am Ende/Anfang eines ist Wort, es gibt null zurück, denke ich, weil es nicht in Reichweite ist. Irgendeine Möglichkeit, es für diesen Fall leicht anzupassen? – mootymoots

+0

Entschuldigung, es funktioniert - mein schlechtes. Wenn das Wort jedoch mit einem # oder @ beginnt, wird das @ oder # nicht registriert - werden sie wegen NSStringEnumerationByWords verpasst? – mootymoots

+0

Ich habe einen Edit gemacht, indem ich 'NSLocationInRange (index, substringRange)' in 'NSLocationInRange (index, enclosingRange)' geändert habe, was dazu führen sollte, dass es ein Wort zurückgibt, selbst wenn Sie auf einer Wortgrenze landen. Ich werde einen Blick auf den @ oder # Fall werfen - würdest du mir ein Beispiel geben und mir sagen, welche Ausgabe du willst? – paulmelnikow

1

ist hier ein eher hackish Weg, es zu tun, aber es funktionieren würde:

NSString hat Methode:

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

so könnten Sie tun:

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

Sie haben es gelöst, gut !!! Aber wo ist Regex wie OP. –

+1

Ich war faul ... Ich überlasse das für jemanden mit mehr Geduld als ich. –

+0

Nice one :) mochte Ihren Sinn für Humor –

Verwandte Themen