如何检查一个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
的自定义设置版本rangeOfCharacterFromSet
caching的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; }