47

我正在开发一个小型 iphone 项目,我需要检查输入的用户名是否仅包含字母数字字符?(A-Z, a-z, 0-9. 我将如何检查它?

4

8 回答 8

86

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

NSString *str = @"aA09";
NSCharacterSet *alphaSet = [NSCharacterSet alphanumericCharacterSet];
BOOL valid = [[str stringByTrimmingCharactersInSet:alphaSet] isEqualToString:@""]; 
于 2009-11-04T04:29:26.077 回答
61

这将起作用:

@implementation NSString (alphaOnly)

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

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

@end
于 2009-11-04T08:02:14.773 回答
9

基于NSCharacterSet的答案没有给出您对日语等文本可能期望的结果,通常声称它们确实包含字母数字字符 - 正在执行的测试归结为“只有字母或数字”,而日语(等)字符计为“信”。

如果您正在尝试检查拉丁字符与外语(例如日语),那么“如何确定 NSString 是否基于拉丁语? ”的答案可能会有所帮助:

BOOL isLatin = [myString canBeConvertedToEncoding:NSISOLatin1StringEncoding];

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

于 2012-07-23T21:09:38.387 回答
9

您可以将此正则表达式库用于 ObjectiveC。使用以下正则表达式进行匹配:

^[a-zA-Z0-9]*$
于 2009-11-04T04:04:13.087 回答
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 函数进行任何测试。

于 2014-10-27T20:16:10.363 回答
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;
    }
}

具有添加/减去空格等新字符的灵活性

PS 这个方法可以复制/粘贴到 NSString 类

于 2014-04-26T23:45:53.213 回答
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
于 2009-11-04T16:46:06.330 回答
1

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

- (BOOL)isAlphanumeric:(NSString *)string {
    return [string rangeOfString:@"^[a-zA-Z0-9]+$" options:NSRegularExpressionSearch].location != NSNotFound;
}
于 2016-03-14T17:08:11.803 回答