如何检查一个string是否只包含目标C中的字母数字字符?

我正在一个小型的iPhone项目,我将需要检查input的用户名是否只包含字母数字字符? (AZ, az, 0-9 。我怎么去检查它?

如果你不想为这个任务引入一个正则expression式库…

 NSString *str = @"aA09"; NSCharacterSet *alphaSet = [NSCharacterSet alphanumericCharacterSet]; BOOL valid = [[str stringByTrimmingCharactersInSet:alphaSet] isEqualToString:@""]; 

这将工作:

 @implementation NSString (alphaOnly) - (BOOL) isAlphaNumeric { NSCharacterSet *unwantedCharacters = [[NSCharacterSet alphanumericCharacterSet] invertedSet]; return ([self rangeOfCharacterFromSet:unwantedCharacters].location == NSNotFound); } @end 

您可以将这个正则expression式库用于ObjectiveC。 使用以下正则expression式来匹配:

 ^[a-zA-Z0-9]*$ 

基于NSCharacterSet的答案没有给出你可能期望的日文等文本的结果,通常声称它们包含字母数字字符 – 正在执行的testing归结为“只有字母或数字”,而日文(等)字符计为“快报”。

如果你想检查拉丁字符与外语(例如日文),那么“ 如何确定NSString是否基于拉丁文? ”的答案可能有助于:

 BOOL isLatin = [myString canBeConvertedToEncoding:NSISOLatin1StringEncoding]; 

NSASCIIStringEncoding也可以用来代替NSISOLatin1StringEncoding来进一步限制有效字符。 之后你也可以使用NSCharacterSet来testing,排除像!,#等特殊字符

我已经进行了一些相当广泛的性能testing,在select如何validation字母数字string时需要考虑几个因素。 首先,当然,你可能不关心性能。 如果你的应用很lessvalidationstring,或者甚至只有一次,那么给你所需行为的任​​何方法都可以。 除此之外,这是我的performance结果。

对于自定义字符集(比如字母数字字符,没有Unicode字符或标记),这对于初始运行来说是最快的:

 NSCharacterSet *alphanumericSet = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"]; NSString *result = [self stringByTrimmingCharactersInSet:alphanumericSet]; return [result isEqualToString:@""]; 

如果你可以使用像[NSCharacterSet alphanumericCharacterSet]这样的预先计算的字符集,那么这是最快的:

 NSCharacterSet *alphanumericSet = [NSCharacterSet alphanumericCharacterSet]; alphanumericSet = alphanumericSet.invertedSet; NSRange range = [self rangeOfCharacterFromSet:alphanumericSet]; return (range.location == NSNotFound); 

如果您重复运行这些validation,则使用dispatch_once将字符集caching到静态variables中可能会有所帮助。 在这种情况下,如果您确定可以吸收初始编译时间,那么使用正则expression式实际上是自定义字符集中最快的:

 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); 

如果不希望使用正则expression式,则caching的rangeOfCharacterFromSet的自定义设置版本rangeOfCharacterFromSetcaching的stringByTrimmingCharactersInCharacterSet:方法:

 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); 

对于预先计算的集合,caching的rangeOfCharacterFromSet:方法再次是最快的:

 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); 

对于每个人的信息, isSupersetOfSet:方法是最慢的,不pipe是否caching。 看起来像isSupersetOfSet:非常慢。

 NSCharacterSet *stringSet = [NSCharacterSet characterSetWithCharactersInString:self]; NSCharacterSet *alphanumericSet = [NSCharacterSet alphanumericCharacterSet]; return [alphanumericSet isSupersetOfSet:stringSet]; 

我没有做任何底层CFCharacterSet函数的testing。

 - (BOOL)isAlphaNumeric { NSCharacterSet *s = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'. "]; s = [s invertedSet]; NSRange r = [self rangeOfCharacterFromSet:s]; if (r.location == NSNotFound) { return NO; } else { return YES; } } 

具有添加/减less像空格这样的新字符的灵活性

PS这种方法可以在NSString类中复制/粘贴

我非常喜欢RegexKit Lite Framework。 它使用ICU正则expression式库,该库已经包含在OSX中,并且是unicode安全的。

 NSString *str = @"testString"; [str isMatchedByRegex:@"^[a-zA-Z0-9]*$"]; // strict ASCII-match [str isMatchedByRegex:@"^[\p{L}\p{N}]*$"]; // unicode letters and numbers match 

您可以使用iOS 3.2中引入的NSString正则expression式function:

 - (BOOL)isAlphanumeric:(NSString *)string { return [string rangeOfString:@"^[a-zA-Z0-9]+$" options:NSRegularExpressionSearch].location != NSNotFound; }