Comment vérifier si une chaîne de caractères ne contient que des caractères alphanumériques dans l'objectif C?

je travaille sur un petit projet iphone et je devrais vérifier si le nom d'utilisateur entré ne contient que des caractères alphanumériques? (A-Z, a-z, 0-9 . Comment puis-je le vérifier?

46
demandé sur Tshepang 2009-11-04 06:58:59

8 réponses

Si vous ne voulez pas mettre dans une bibliothèque regex pour cette tâche...

NSString *str = @"aA09";
NSCharacterSet *alphaSet = [NSCharacterSet alphanumericCharacterSet];
BOOL valid = [[str stringByTrimmingCharactersInSet:alphaSet] isEqualToString:@""]; 
86
répondu Jason Harwig 2009-11-04 08:16:58

Cela va fonctionner:

@implementation NSString (alphaOnly)

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

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

@end
61
répondu NSResponder 2015-08-19 21:17:08

vous pouvez utiliser cette bibliothèque d'expression régulière pour ObjectiveC. Utilisez le regex suivant pour correspondre:

^[a-zA-Z0-9]*$
9
répondu Soviut 2009-11-04 04:04:13

les réponses basées sur NSCharacterSet ne donnent pas les résultats que vous pourriez attendre pour le texte japonais etc, affirmant souvent qu'elles contiennent des caractères alphanumériques - le test effectué se résume à "n'y a-t-il que des lettres ou des chiffres", et les caractères japonais (etc) comptent comme des "lettres".

si vous essayez de vérifier les caractères latins vs une langue étrangère (par ex. Japonais), puis la réponse de " Comment déterminer si un NSString est basé sur le latin? " peut aider:

BOOL isLatin = [myString canBeConvertedToEncoding:NSISOLatin1StringEncoding];

NSASCIIStringEncoding peut également être utilisé à la place du NSISOLatin1StringEncoding pour restreindre davantage les caractères valides. Vous pouvez également tester en utilisant NSCharacterSet après, pour exclure des caractères spéciaux comme !, #, etc.

8
répondu JosephH 2017-05-23 12:17:14

j'ai effectué des tests de performance assez approfondis et il y a plusieurs considérations à prendre en compte lors du choix de la façon de valider vos chaînes alphanumériques. Tout d'abord, bien sûr, c'est que vous ne vous souciez peut-être même pas de la performance. Si votre application valide rarement les chaînes, ou peut-être même ne le fait qu'une seule fois, quelle que soit la méthode qui vous donne le comportement que vous voulez est très bien. Au-delà, voici mes résultats de performance.

Pour les jeux de caractères personnalisés (dire caractères alphanumériques, sans caractères Unicode ni marques), c'est le plus rapide pour une première exécution:

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

return [result isEqualToString:@""];

si vous êtes d'accord en utilisant un jeu de caractères précalculé comme [NSCharacterSet alphanumericCharacterSet] alors c'était le plus rapide:

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

return (range.location == NSNotFound);

Cacher le jeu de caractères dans une variable statique en utilisant dispatch_once peut aider beaucoup si vous exécutez ces validations à plusieurs reprises. Dans ce cas, si vous êtes certain que vous pouvez absorber le temps de compilation initial, en utilisant un regex en fait, il s'avère être le plus rapide pour les jeux de caractères personnalisés:

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);

si vous ne souhaitez pas utiliser le regex, la version personnalisée de la mise en cache rangeOfCharacterFromSet contourne la mise en cache stringByTrimmingCharactersInCharacterSet: méthode:

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);

pour les ensembles précalculés, la méthode rangeOfCharacterFromSet: mise en cache est de nouveau la plus rapide:

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);

et pour information, la méthode isSupersetOfSet: était la plus lente, qu'elle soit mise en cache ou pas. On dirait que isSupersetOfSet: est plutôt lent.

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

return [alphanumericSet isSupersetOfSet:stringSet];

Je n'ai pas testé les fonctions sous-jacentes de CFCharacterSet.

5
répondu Jon Shier 2014-10-27 20:16:10
- (BOOL)isAlphaNumeric
{
     NSCharacterSet *s = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'. "];
     s = [s invertedSet];
     NSRange r = [self rangeOfCharacterFromSet:s];
     if (r.location == NSNotFound) {
         return NO;
     } else {
       return YES;
    }
}

a la flexibilité d'ajouter/ soustraire de nouveaux caractères comme des espaces

P. S cette méthode peut être copiée / collée dans la catégorie NSString

3
répondu carelesslyChoosy 2014-05-31 03:43:00

j'aime vraiment le RegexKit Lite Cadre de. Il utilise la bibliothèque ICU regex, qui est déjà incluse avec OSX et est unicode-safe.

NSString *str = @"testString";
[str isMatchedByRegex:@"^[a-zA-Z0-9]*$"]; // strict ASCII-match
[str isMatchedByRegex:@"^[\p{L}\p{N}]*$"]; // unicode letters and numbers match
2
répondu Adrian 2009-11-04 16:46:06

vous pouvez utiliser NSString capacité d'expression régulière, introduit dans iOS 3.2:

- (BOOL)isAlphanumeric:(NSString *)string {
    return [string rangeOfString:@"^[a-zA-Z0-9]+$" options:NSRegularExpressionSearch].location != NSNotFound;
}
0
répondu Rob 2016-03-14 17:08:11