I'm looking for a quick and easy way to strip non-alphanumeric characters from an NSString
. Probably something using an NSCharacterSet
, but I'm tired and nothing seems to return a string containing only the alphanumeric characters in a string.

- 18,205
- 17
- 69
- 103

- 19,021
- 6
- 70
- 80
-
5+1 for being one of the 5% of questions properly tagged as cocoa and not objective-c – Nektarios Sep 11 '11 at 23:45
9 Answers
We can do this by splitting and then joining. Requires OS X 10.5+ for the componentsSeparatedByCharactersInSet:
NSCharacterSet *charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
NSString *strippedReplacement = [[someString componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:@""];

- 30,736
- 10
- 83
- 104
-
2What are alphanumeric characters? E.g. would German "Umlaute", like ä, ö or ü be included in the set and hence not be trimmed? – Erik Jan 30 '13 at 20:50
-
3To handle accented characters you need to create a NSMutableCharacterSet that is a union of alphanumericCharacterSet and nonBaseCharacterSet, and invert that – Greg Fodor Jul 16 '13 at 05:25
-
1The `trimmedReplacement` is misleading. In all iOS NSString invocations, *trimmed* means from start and end. May I suggest **occurrencesReplacement** or **strippedReplacement** instead? – SwiftArchitect May 19 '15 at 22:18
-
-
4@datayeah No worries, just change the first line to invert the 'Portable Filename Character Set' as per http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_277: `NSCharacterSet *charactersToRemove = [[NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"] invertedSet];` – Erik Nov 14 '15 at 19:36
In Swift, the componentsJoinedByString
is replaced by join(...)
, so here it just replaces non-alphanumeric characters with a space.
let charactersToRemove = NSCharacterSet.alphanumericCharacterSet().invertedSet
let strippedReplacement = " ".join(someString.componentsSeparatedByCharactersInSet(charactersToRemove))
For Swift2 ...
var enteredByUser = field.text .. or whatever
let unsafeChars = NSCharacterSet.alphanumericCharacterSet().invertedSet
enteredByUser = enteredByUser
.componentsSeparatedByCharactersInSet(unsafeChars)
.joinWithSeparator("")
If you want to delete just the one character, for example delete all returns...
enteredByUser = enteredByUser
.componentsSeparatedByString("\n")
.joinWithSeparator("")

- 2,313
- 1
- 22
- 23
What I wound up doing was creating an NSCharacterSet and the -invertedSet
method that I found (it's a wonder what an extra hour of sleep does for documentation-reading abilities). Here's the code snippet, assuming that someString
is the string from which you want to remove non-alphanumeric characters:
NSCharacterSet *charactersToRemove =
[[ NSCharacterSet alphanumericCharacterSet ] invertedSet ];
NSString *trimmedReplacement =
[ someString stringByTrimmingCharactersInSet:charactersToRemove ];
trimmedReplacement
will then contain someString
's alphanumeric characters.

- 19,021
- 6
- 70
- 80
-
26FYI, stringByTrimmingCharactersInSet: only removes characters from the beginning and end of the string. Maybe that's what you wanted. – Ken Aspeslagh Jan 19 '10 at 16:14
-
Hmm, good point, Ken. I didn't know that. It still works for my needs, but that's good to know. – Jeff Kelley Jan 19 '10 at 16:40
Swift 3 version of accepted answer:
let unsafeChars = CharacterSet.alphanumerics.inverted
let myStrippedString = myString.components(separatedBy: unsafeChars).joined(separator: "")

- 10,930
- 1
- 56
- 72
Swift 5, Extension:
extension String {
/// Will strip all non alpha characters from a string
public var alpha: String {
return components(separatedBy: CharacterSet.alphanumerics.inverted).joined()
}
}

- 1,434
- 17
- 16
A Cleanup Category
I have a method call stringByStrippingCharactersInSet:
and stringByCollapsingWhitespace
that might be convenient to just 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

- 21,528
- 7
- 125
- 126
Here’s a Swift version of Cameron’s category as an extension:
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(" ")
}
}

- 1
- 1

- 5,981
- 3
- 21
- 24
The plain cycle would be the faster execution time I think:
@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

- 1
This is a more effective way than the provided answer
+ (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;
}
or as a Category
@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

- 19,915
- 16
- 123
- 179