2013-03-13 18 views
5

Voglio estrarre una sottostringa da un NSString in un dato indice. Esempio:Estrazione della sottostringa di parole da NSString all'indice dato

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

punto di riferimento del '9' si trova nel mezzo della parola 'benvenuto', e mi piacerebbe essere in grado di estrarre quella parola 'benvenuto' come una stringa. Qualcuno può dirmi come raggiungerei questo? Con una regex?

+0

vuoi 'e' o 'benvenuto'? –

+0

Voglio la parola "benvenuto" – mootymoots

+0

Questa domanda non è valida? Perché qualcuno andrebbe a trovarlo con regex o nsset? può essere trovato abbastanza facilmente con i metodi della classe nsstring. –

risposta

9

Ecco una soluzione come categoria su 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; 
} 

E un altro, che è più complicato ma permette di specificare esattamente i caratteri parola che si desidera:

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

La seconda versione è anche più efficiente con stringhe lunghe, assumendo le parole sono brevi.

+0

quindi questo è un buon ringraziamento, anche se l'indice è alla fine/inizio di un parola, restituisce null, immagino perché non è nel raggio d'azione. Qualche modo di adattarlo leggermente per quel caso? – mootymoots

+0

scusa, funziona - mio male. Tuttavia, se la parola inizia con un # o @ non registra il numero @ o # - vengono persi a causa di NSStringEnumerationByWords? – mootymoots

+0

Ho apportato una modifica, cambiando 'NSLocationInRange (index, substringRange)' a 'NSLocationInRange (index, enclosingRange)' che dovrebbe far sì che restituisca una parola anche se atterri su un limite di parole. Sbircherò il caso @ o # - potresti darmi un esempio e dirmi quale output vuoi? – paulmelnikow

1

Ecco un modo piuttosto hacker per farlo, ma avrebbe funzionato:

NSString ha un metodo:

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

Così si potrebbe fare:

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

hai risolto, BUON !!! Ma dove è regex come da OP. –

+1

Ero pigro ... Lo lascerò per qualcuno con più pazienza di me. –

+0

Bello uno :) mi è piaciuto il tuo senso dell'umorismo –

Problemi correlati