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

时间:2009-11-04 03:59:00

标签: iphone objective-c string alphanumeric

我正在开发一个小型iphone项目,我需要检查输入的userName是否只包含字母数字字符? (A-Z, a-z, 0-9。我该如何检查?

8 个答案:

答案 0 :(得分:86)

如果您不想为这一项任务引入正则表达式库...

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

答案 1 :(得分:61)

这将有效:

@implementation NSString (alphaOnly)

- (BOOL) isAlphaNumeric
{
    NSCharacterSet *unwantedCharacters = 
       [[NSCharacterSet alphanumericCharacterSet] invertedSet];

    return ([self rangeOfCharacterFromSet:unwantedCharacters].location == NSNotFound);
}

@end

答案 2 :(得分:9)

您可以将this regular expression library用于ObjectiveC。使用以下正则表达式匹配:

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

答案 3 :(得分:8)

NSCharacterSet基于BOOL isLatin = [myString canBeConvertedToEncoding:NSISOLatin1StringEncoding]; 的答案不会给出您对日语等文本所期望的结果,通常声称它们确实包含字母数字字符 - 正在执行的测试归结为“只有字母或数字”,以及日语(等)字符计为“字母”。

如果您正在尝试检查拉丁字符与外语(例如日语),那么“How to determine if an NSString is latin based?”的答案可能会有所帮助:

NSASCIIStringEncoding
也可以使用

{{1}}代替NSISOLatin1StringEncoding来进一步限制有效字符。您也可以在之后使用NSCharacterSet进行测试,以排除特殊字符,如!,#等。

答案 4 :(得分:5)

我已经进行了一些相当广泛的性能测试,在选择如何验证字母数字字符串时需要考虑几个因素。首先,当然,你可能甚至不关心表现。如果您的应用程序很少验证字符串,或者甚至只执行一次,那么无论采用哪种方法,您都可以获得所需的行为。除此之外,这是我的表现结果。

对于自定义字符集(例如字母数字字符,没有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函数进行任何测试。

答案 5 :(得分:3)

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

可以灵活地添加/减去像空格一样的新字符

P.S此方法可以在NSString类别中复制/粘贴

答案 6 :(得分:2)

我非常喜欢RegexKit Lite 框架。它使用ICU正则表达式库,它已经包含在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

答案 7 :(得分:0)

您可以使用iOS 3.2中引入的NSString正则表达式功能:

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