Подтвердить что ты не робот

Как проверить, содержит ли строка только буквенно-цифровые символы в объекте C?

Я работаю над небольшим проектом iphone, и мне нужно будет проверить, содержит ли введенное имя пользователя только буквенно-цифровые символы? (A-Z, a-z, 0-9. Как я могу проверить его?

4b9b3361

Ответ 1

Если вы не хотите вводить библиотеку регулярных выражений для этой одной задачи...

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

Ответ 2

Это будет работать:

@implementation NSString (alphaOnly)

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

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

@end

Ответ 4

Ответы на основе NSCharacterSet не дают результатов, которые вы могли бы ожидать для японского и т.д. текста, часто заявляя, что они содержат буквенно-цифровые символы. Выполнение теста сводится к тому, что "есть только буквы или цифры" и японский ( и т.д.) символы считаются "Письмами".

Если вы пытаетесь проверить латинские символы на иностранном языке (например, на японском языке), тогда ответ из Как определить, является ли NSString латинским? "может помочь:

BOOL isLatin = [myString canBeConvertedToEncoding:NSISOLatin1StringEncoding];

NSASCIIStringEncoding также может использоваться вместо NSISOLatin1StringEncoding для дальнейшего ограничения допустимых символов. После этого вы также можете протестировать, используя NSCharacterSet, чтобы исключить специальные символы, такие как!, # И т.д.

Ответ 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.

Ответ 6

- (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

Ответ 7

Мне очень нравится RegexKit Lite Framework. Он использует библиотеку регулярных выражений 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

Ответ 8

Вы можете использовать возможности регулярного выражения NSString, представленные в iOS 3.2:

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