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

Che*_*Lai 47 string iphone alphanumeric objective-c

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

Jas*_*wig 86

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

NSString *str = @"aA09";
NSCharacterSet *alphaSet = [NSCharacterSet alphanumericCharacterSet];
BOOL valid = [[str stringByTrimmingCharactersInSet:alphaSet] isEqualToString:@""]; 
Run Code Online (Sandbox Code Playgroud)

  • 这只会检查字符串两端的字符,而不是整个字符串 (4认同)
  • https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/stringByTrimmingCharactersInSet:我引用:"返回一个通过从给定字符集中包含的接收者字符的**两端**中删除而产生的新字符串" (4认同)
  • 不正确.`NSCharacterSet.alphanumericCharacterSet`包含比`[a-zA-Z0-9]`更多的字符,例如,变音符号(如é)和上标(如²)./sf/ask/117012381/#comment59629782_1672310 (4认同)

NSR*_*der 61

这将有效:

@implementation NSString (alphaOnly)

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

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

@end
Run Code Online (Sandbox Code Playgroud)

  • `?是的:不是没有必要的.逻辑比较的结果已经是布尔值. (11认同)
  • 虽然没有被标记为海报的答案,但我喜欢这个解决方案比标记为答案更好.它非常有用,并且可以轻松扩展以便与其他字符集进行测试.大拇指. (6认同)
  • 不正确.`NSCharacterSet.alphanumericCharacterSet`包含比`[a-zA-Z0-9]`更多的字符,例如,变音符号(如é)和上标(如²)./sf/ask/117012381/#comment59629685_1671671 (4认同)

Sov*_*iut 9

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

^[a-zA-Z0-9]*$
Run Code Online (Sandbox Code Playgroud)


Jos*_*phH 8

NSCharacterSet基于答案不给你所期望的日本等文本的结果,往往声称他们确实包含字母数字字符-被执行的测试归结为"在那里只有字母或数字",以及日本(等)字符算作"快报.

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

BOOL isLatin = [myString canBeConvertedToEncoding:NSISOLatin1StringEncoding];
Run Code Online (Sandbox Code Playgroud)

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


Jon*_*ier 5

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

对于自定义字符集(例如字母数字字符,不包含Unicode字符或标记),这对于初始运行来说速度最快:

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

return [result isEqualToString:@""];
Run Code Online (Sandbox Code Playgroud)

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

NSCharacterSet *alphanumericSet = [NSCharacterSet alphanumericCharacterSet];
alphanumericSet = alphanumericSet.invertedSet;
NSRange range = [self rangeOfCharacterFromSet:alphanumericSet];

return (range.location == NSNotFound);
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

如果您不希望使用正则表达式,则缓存的自定义集版本将缓存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);
Run Code Online (Sandbox Code Playgroud)

对于预先计算的集合,缓存的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);
Run Code Online (Sandbox Code Playgroud)

并且对于每个人的信息,该isSupersetOfSet:方法是最慢的,无论是否缓存.看起来isSupersetOfSet:很慢.

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

return [alphanumericSet isSupersetOfSet:stringSet];
Run Code Online (Sandbox Code Playgroud)

我没有对底层的CFCharacterSet函数进行任何测试.