我正在开发一个小型的iPhone项目,需要检查输入的用户名是否只包含字母数字字符?(A-Z, a-z, 0-9)
。我该如何进行检查?
我正在开发一个小型的iPhone项目,需要检查输入的用户名是否只包含字母数字字符?(A-Z, a-z, 0-9)
。我该如何进行检查?
如果您不想为这个任务引入正则表达式库...
NSString *str = @"aA09";
NSCharacterSet *alphaSet = [NSCharacterSet alphanumericCharacterSet];
BOOL valid = [[str stringByTrimmingCharactersInSet:alphaSet] isEqualToString:@""];
stringByReplaceCharacterSet
的东西。 - ragamufinNSCharacterSet.alphanumericCharacterSet
包含的字符比[a-zA-Z0-9]
多得多,例如变音符(如é)和上标符号(如²)。https://dev59.com/eHI-5IYBdhLWcg3wy7wd#1q6hEYcBWogLw_1bEMAh - ma11hew28这将会起作用:
@implementation NSString (alphaOnly)
- (BOOL) isAlphaNumeric
{
NSCharacterSet *unwantedCharacters =
[[NSCharacterSet alphanumericCharacterSet] invertedSet];
return ([self rangeOfCharacterFromSet:unwantedCharacters].location == NSNotFound) ? YES : NO;
}
@end
? YES : NO
并不是必要的。 - ChuckNSCharacterSet.alphanumericCharacterSet
包含比[a-zA-Z0-9]
更多的字符,例如变音符(如é)和上标(如²)。https://stackoverflow.com/questions/1671605/how-to-check-if-a-string-only-contains-alphanumeric-characters-in-objective-c/1671671#comment59629685_1671671 - ma11hew28NSCharacterSet
基于的答案并不能给出您在处理日文等文本时所期望的结果,通常会声称它们包含字母数字字符-测试的核心是“只有字母或数字”,而日语(等)字符被视为“字母”。BOOL isLatin = [myString canBeConvertedToEncoding:NSISOLatin1StringEncoding];
NSASCIIStringEncoding
可以替代 NSISOLatin1StringEncoding 以进一步限制有效字符。您也可以使用 NSCharacterSet 进行测试,以排除特殊字符,如 !、# 等。
我进行了一些相当广泛的性能测试,并且在选择如何验证您的字母数字字符串时需要考虑几个因素。首先,当然,您可能甚至不关心性能。如果您的应用程序很少验证字符串,或者甚至只验证一次,任何能够给出您想要的行为的方法都可以接受。除此之外,这是我的性能测试结果。
对于自定义字符集(例如仅包含字母数字字符,而不包含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);
如果您需要多次运行这些验证,则使用dispatch_once
将字符集缓存到静态变量中会非常有帮助。在这种情况下,如果您确信可以吸收初始编译时间,那么使用正则表达式实际上是自定义字符集最快的方法:
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);
如果你不想使用正则表达式,那么自定义集合版本的缓存rangeOfCharacterFromSet
比缓存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);
对于预先计算好的集合,缓存的 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:
方法都是最慢的。看起来isSupersetOfSet:
很慢。
NSCharacterSet *stringSet = [NSCharacterSet characterSetWithCharactersInString:self];
NSCharacterSet *alphanumericSet = [NSCharacterSet alphanumericCharacterSet];
return [alphanumericSet isSupersetOfSet:stringSet];
我没有对底层的 CFCharacterSet 函数进行任何测试。
- (BOOL)isAlphaNumeric
{
NSCharacterSet *s = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'. "];
s = [s invertedSet];
NSRange r = [self rangeOfCharacterFromSet:s];
if (r.location == NSNotFound) {
return NO;
} else {
return YES;
}
}
具有添加/删除空格等新字符的灵活性
附:此方法可复制/粘贴在NSString类别中
return r.location == NSNotFound;
。 - agmezrr.location != NSNotFound
,也就是说,如果在不需要的集合中没有找到,则为字母数字。我认为你把它倒过来了。 - DuckNSString *str = @"testString";
[str isMatchedByRegex:@"^[a-zA-Z0-9]*$"]; // strict ASCII-match
[str isMatchedByRegex:@"^[\p{L}\p{N}]*$"]; // unicode letters and numbers match
NSString
正则表达式功能:- (BOOL)isAlphanumeric:(NSString *)string {
return [string rangeOfString:@"^[a-zA-Z0-9]+$" options:NSRegularExpressionSearch].location != NSNotFound;
}