Remover caracteres não alfanuméricos de um NSString

Estou procurando uma maneira rápida e fácil de remover caracteres não alfanuméricos de um NSString . Provavelmente algo usando um NSCharacterSet , mas estou cansado e nada parece retornar uma string contendo apenas os caracteres alfanuméricos em uma string.

Podemos fazer isso dividindo e juntando. Requer o OS X 10.5+ para os componentsSeparatedByCharactersInSet:

 NSCharacterSet *charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet]; NSString *strippedReplacement = [[someString componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:@""]; 

No Swift, o componentsJoinedByString é substituído por join(...) , então aqui apenas substitui caracteres não alfanuméricos por um espaço.

 let charactersToRemove = NSCharacterSet.alphanumericCharacterSet().invertedSet let strippedReplacement = " ".join(someString.componentsSeparatedByCharactersInSet(charactersToRemove)) 

Para o Swift2 …

 var enteredByUser = field.text .. or whatever let unsafeChars = NSCharacterSet.alphanumericCharacterSet().invertedSet enteredByUser = enteredByUser .componentsSeparatedByCharactersInSet(unsafeChars) .joinWithSeparator("") 

Se você quiser excluir apenas um caractere, por exemplo, exclua todos os retornos …

  enteredByUser = enteredByUser .componentsSeparatedByString("\n") .joinWithSeparator("") 

O que acabei fazendo foi criar um NSCharacterSet e o método -invertedSet que eu encontrei (é uma maravilha o que uma hora extra de sono faz para habilidades de leitura de documentação). Aqui está o trecho de código, assumindo que someString é a string da qual você deseja remover os caracteres não alfanuméricos:

 NSCharacterSet *charactersToRemove = [[ NSCharacterSet alphanumericCharacterSet ] invertedSet ]; NSString *trimmedReplacement = [ someString stringByTrimmingCharactersInSet:charactersToRemove ]; 

trimmedReplacement conterá caracteres alfanuméricos de someString .

Swift 3 versão da resposta aceita:

 let unsafeChars = CharacterSet.alphanumerics.inverted let myStrippedString = myString.components(separatedBy: unsafeChars).joined(separator: "") 

Uma categoria de limpeza

Eu tenho uma chamada de método stringByStrippingCharactersInSet: e stringByCollapsingWhitespace que pode ser conveniente para apenas drop-in.

 @implementation NSString (Cleanup) - (NSString *)clp_stringByStrippingCharactersInSet:(NSCharacterSet *)set { return [[self componentsSeparatedByCharactersInSet:set] componentsJoinedByString:@""]; } - (NSString *)clp_stringByCollapsingWhitespace { NSArray *components = [self componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; components = [components filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self <> ''"]]; return [components componentsJoinedByString:@" "]; } @end 

Aqui está uma versão Swift da categoria de Cameron como uma extensão:

 extension String { func stringByStrippingCharactersInSet(set:NSCharacterSet) -> String { return (self.componentsSeparatedByCharactersInSet(set) as NSArray).componentsJoinedByString("") } func stringByCollapsingWhitespace() -> String { var components:NSArray = self.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) let predicate = NSPredicate(format: "self <> ''", argumentArray: nil) components = components.filteredArrayUsingPredicate(predicate) return components.componentsJoinedByString(" ") } } 

O ciclo simples seria o tempo de execução mais rápido que eu acho:

 @implementation NSString(MyUtil) - (NSString*) stripNonNumbers { NSMutableString* res = [NSMutableString new]; //NSCharacterSet *numericSet = [NSCharacterSet decimalDigitCharacterSet]; for ( int i=0; i < self.length; ++i ) { unichar c = [self characterAtIndex:i]; if ( c >= '0' && c <= '9' ) // this looks cleaner, but a bit slower: [numericSet characterIsMember:c]) [res appendFormat:@"%c", c]; } return res; } @end 

Esta é uma maneira mais eficaz do que a resposta fornecida

 + (NSString *)alphanumericString:(NSString *)s { NSCharacterSet * charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet]; NSMutableString * ms = [NSMutableString stringWithCapacity:[s length]]; for (NSInteger i = 0; i < s.length; ++i) { unichar c = [s characterAtIndex:i]; if (![charactersToRemove characterIsMember:c]) { [ms appendFormat:@"%c", c]; } } return ms; } 

ou como uma categoria

 @implementation NSString (Alphanumeric) - (NSString *)alphanumericString { NSCharacterSet * charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet]; NSMutableString * ms = [NSMutableString stringWithCapacity:[self length]]; for (NSInteger i = 0; i < self.length; ++i) { unichar c = [self characterAtIndex:i]; if (![charactersToRemove characterIsMember:c]) { [ms appendFormat:@"%c", c]; } } return ms; } @end