I'm working on a small iphone project and i would need to check if the userName entered only contains alphanumerical characters? (A-Z, a-z, 0-9
. How would i go about checking it?
-
In Swift: http://stackoverflow.com/questions/35992800/check-if-a-string-is-alphanumeric-in-swift – ma11hew28 Mar 14 '16 at 16:23
8 Answers
If you don't want to bring in a regex library for this one task...
NSString *str = @"aA09";
NSCharacterSet *alphaSet = [NSCharacterSet alphanumericCharacterSet];
BOOL valid = [[str stringByTrimmingCharactersInSet:alphaSet] isEqualToString:@""];

- 234,037
- 30
- 302
- 389

- 43,743
- 5
- 43
- 44
-
thz alot dude i was thinking something along the same line as you, but just couldn't figure out how – Cheng Lai Nov 04 '09 at 06:34
-
4This only checks for the characters on both ends of the string by the way and not the entire string – ragamufin May 03 '12 at 06:54
-
@ragamufin is incorrect, the above code does check the whole string, not just the end characters. – Albert Renshaw Jan 15 '14 at 21:24
-
4https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/stringByTrimmingCharactersInSet: I quote: "Returns a new string made by removing from both **ends** of the receiver characters contained in a given character set" – ragamufin Jan 16 '14 at 01:19
-
@ragamufin You are correct in that it only trims the ends, but that accomplishes the task required. If after trimming both ends an empty string remains then we know that all the characters were alphanumeric. – Jason Harwig Jan 16 '14 at 15:12
-
1The op's question is to make sure the string contains **only** alphanumeric characters. I guess this is an indirect way of doing it so sure, it accomplishes the task I'll give you that. Still, it would seem to me something more along the lines of `stringByReplaceCharacterSet` would be better suited. – ragamufin Jan 16 '14 at 23:51
-
1This is a waste of CPU cycles and RAM, in case you're worried about that. It would be better to just scan the string until a non-alphanumeric character is found. – sudo Apr 23 '14 at 18:42
-
4Incorrect. `NSCharacterSet.alphanumericCharacterSet` includes a lot more characters than `[a-zA-Z0-9]`, e.g., diacritics (like é) & superscripts (like ²). https://stackoverflow.com/questions/1671605/how-to-check-if-a-string-only-contains-alphanumeric-characters-in-objective-c/1671671#comment59629782_1672310 – ma11hew28 Mar 14 '16 at 13:25
This will work:
@implementation NSString (alphaOnly)
- (BOOL) isAlphaNumeric
{
NSCharacterSet *unwantedCharacters =
[[NSCharacterSet alphanumericCharacterSet] invertedSet];
return ([self rangeOfCharacterFromSet:unwantedCharacters].location == NSNotFound) ? YES : NO;
}
@end

- 16,861
- 7
- 32
- 46
-
11The `? YES : NO` isn't really necessary. The result of a logical comparison is already a boolean value. – Chuck Nov 04 '09 at 08:10
-
1I know, I just like to see it so that I don't read it later and think I left something out. – NSResponder Nov 04 '09 at 08:13
-
hey that's nice too man i didn't know u could invert the character set. lol wonder how does that work for other languages like Chinese – Cheng Lai Nov 09 '09 at 04:06
-
Works the same for all character sets. Unicode is well-supported in Cocoa. – NSResponder Nov 09 '09 at 13:01
-
6While not flagged to be the answer by the poster, I like this solution better than one marked as the answer. It's really useful and can be extended easily for testing against other character sets as well. Thumb up. – scottbates22 Mar 18 '10 at 20:11
-
@NSResponder How much data does this code occupy? It seems making an inverted set of literally every unicode character except for 62 of them (alphanumerics) would be very data heavy. – Albert Renshaw Jan 15 '14 at 21:25
-
1Albert, you can rest assured that the CoreFoundation team is a bit smarter than that. – NSResponder Jan 16 '14 at 15:25
-
4Incorrect. `NSCharacterSet.alphanumericCharacterSet` includes a lot more characters than `[a-zA-Z0-9]`, e.g., diacritics (like é) & superscripts (like ²). https://stackoverflow.com/questions/1671605/how-to-check-if-a-string-only-contains-alphanumeric-characters-in-objective-c/1671671#comment59629685_1671671 – ma11hew28 Mar 14 '16 at 13:21
The NSCharacterSet
based answers do not give the results you might expect for Japanese etc text, often claiming that they do contain alphanumeric characters - the test being performed boils down to 'are there only letters or numbers', and Japanese (etc) characters count as 'Letters'.
If you're trying to check Latin characters vs a foreign language (eg. Japanese), then the answer from " How to determine if an NSString is latin based? " may help:
BOOL isLatin = [myString canBeConvertedToEncoding:NSISOLatin1StringEncoding];
NSASCIIStringEncoding
could also be used instead of NSISOLatin1StringEncoding to further restrict the valid characters. You could also test using NSCharacterSet afterwards, to exclude special characters like !, #, etc.
-
Special characters like '#', '@', etc. can also be converted to latin encoding, so this method works only for latin vs. locale-specific check. – Sergiy Salyuk Apr 09 '13 at 15:56
You can use this regular expression library for ObjectiveC. Use the following regex to match:
^[a-zA-Z0-9]*$

- 88,194
- 49
- 192
- 260
-
1Why is it overkill? It's the simplest solution, easy to read and string validation is what regex was intended for. – Soviut Jan 18 '15 at 05:36
I've run some rather extensive performance testing and there are several considerations to take into account when choosing how to validate your alphanumeric strings. First, of course, is that you may not even care about performance. If your app rarely validates strings, or perhaps even only does it once, whatever method that gives you the behavior you want is fine. Beyond that, here are my performance results.
For custom character sets (say alphanumeric characters, without Unicode characters or marks), this is fastest for an initial run:
NSCharacterSet *alphanumericSet = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"];
NSString *result = [self stringByTrimmingCharactersInSet:alphanumericSet];
return [result isEqualToString:@""];
If you're okay using a precomputed character set like [NSCharacterSet alphanumericCharacterSet]
then this was fastest:
NSCharacterSet *alphanumericSet = [NSCharacterSet alphanumericCharacterSet];
alphanumericSet = alphanumericSet.invertedSet;
NSRange range = [self rangeOfCharacterFromSet:alphanumericSet];
return (range.location == NSNotFound);
Caching the character set in a static variable using dispatch_once
can help quite a bit if you run these validations repeatedly. In that case, if you're certain you can absorb the initial compilation time, using a regex actually turns out to be the fastest for custom character sets:
static NSRegularExpression *alphanumericRegex;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
alphanumericRegex = [NSRegularExpression regularExpressionWithPattern:@"^[a-zA-Z0-9]*$" options:NSRegularExpressionCaseInsensitive error:nil];
});
NSUInteger numberOfMatches = [alphanumericRegex numberOfMatchesInString:self options:0 range:NSMakeRange(0, self.length)];
return (numberOfMatches == 1);
If you don't wish to use the regex, the custom set version of the cached rangeOfCharacterFromSet
edges out the cached stringByTrimmingCharactersInCharacterSet:
method:
static NSCharacterSet *alphanumericSet;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
alphanumericSet = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"];
alphanumericSet = alphanumericSet.invertedSet;
});
NSRange range = [self rangeOfCharacterFromSet:alphanumericSet];
return (range.location == NSNotFound);
For precomputed sets, the cached rangeOfCharacterFromSet:
method was again the fastest:
static NSCharacterSet *alphanumericSet;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
alphanumericSet = [NSCharacterSet alphanumericCharacterSet];
alphanumericSet = alphanumericSet.invertedSet;
});
NSRange range = [self rangeOfCharacterFromSet:alphanumericSet];
return (range.location == NSNotFound);
And for everyone's information, the isSupersetOfSet:
method was the slowest, whether cached or not. Looks like isSupersetOfSet:
is pretty slow.
NSCharacterSet *stringSet = [NSCharacterSet characterSetWithCharactersInString:self];
NSCharacterSet *alphanumericSet = [NSCharacterSet alphanumericCharacterSet];
return [alphanumericSet isSupersetOfSet:stringSet];
I didn't do any testing of the underlying CFCharacterSet functions.

- 12,200
- 3
- 35
- 37
-
Great answer. Lots of little gotchas with [NSCharacterSet alphanumericCharacterSet]. The simple and inelegant "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" was exactly what I needed to avoid Chinese/Japanese characters in the alphanumeric detection. – JeremyDay Jan 23 '16 at 02:00
- (BOOL)isAlphaNumeric
{
NSCharacterSet *s = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'. "];
s = [s invertedSet];
NSRange r = [self rangeOfCharacterFromSet:s];
if (r.location == NSNotFound) {
return NO;
} else {
return YES;
}
}
Has the flexibility to add/ subtract new characters like whitespaces
P.S This method can be copy/paste in NSString category

- 7,880
- 1
- 23
- 33
-
4I think you can change the last piece of code to `return r.location == NSNotFound;` – agmezr May 29 '14 at 18:46
-
should't it be `r.location != NSNotFound` in your code? that is, if not found on the unwanted set, then alphanumeric. I think you have that inverted. – Duck Dec 20 '19 at 10:26
I really like the RegexKit Lite Framework. It uses the ICU regex library, which is already included with OSX and is unicode-safe.
NSString *str = @"testString";
[str isMatchedByRegex:@"^[a-zA-Z0-9]*$"]; // strict ASCII-match
[str isMatchedByRegex:@"^[\p{L}\p{N}]*$"]; // unicode letters and numbers match

- 994
- 5
- 5
You can use NSString
regular expression capabilities, introduced in iOS 3.2:
- (BOOL)isAlphanumeric:(NSString *)string {
return [string rangeOfString:@"^[a-zA-Z0-9]+$" options:NSRegularExpressionSearch].location != NSNotFound;
}

- 415,655
- 72
- 787
- 1,044
-
This is far too primitive, since: 1) Regular Expressions do NOT fully cover the Unicode set, only much simpler subsets. 2) Unicode contains lots of "alphanumeric" characters aside from the ones specified here – Motti Shneor Apr 17 '23 at 10:22
-
Lol. Yes, it is limited, but deliberately so, as that is explicitly what the OP requested, namely, “A-Z, a-z, 0-9”. FWIW, frequently when you want alphanumerics, you explicitly do *not* want all those other Unicode characters. It depends entirely upon the use-case. – Rob Apr 17 '23 at 14:29