Sto lavorando su un piccolo progetto per iPhone e dovrei controllare se il nome utente inserito contiene solo caratteri alfanumerici? (A-Z, a-z, 0-9
. Come andrei a controllarlo?Come verificare se una stringa contiene solo caratteri alfanumerici nell'obiettivo C?
risposta
Se non si vuole portare in una libreria regex per questo compito ...
NSString *str = @"aA09";
NSCharacterSet *alphaSet = [NSCharacterSet alphanumericCharacterSet];
BOOL valid = [[str stringByTrimmingCharactersInSet:alphaSet] isEqualToString:@""];
È possibile utilizzare this regular expression library per ObjectiveC. Utilizzare la seguente espressione regolare per abbinare:
^[a-zA-Z0-9]*$
questo funzionerà:
@implementation NSString (alphaOnly)
- (BOOL) isAlphaNumeric
{
NSCharacterSet *unwantedCharacters =
[[NSCharacterSet alphanumericCharacterSet] invertedSet];
return ([self rangeOfCharacterFromSet:unwantedCharacters].location == NSNotFound);
}
@end
Il '? SÌ: NO' non è realmente necessario. Il risultato di un confronto logico è già un valore booleano. – Chuck
Lo so, mi piace solo vederlo in modo che non lo legga più tardi e penso di aver lasciato qualcosa. – NSResponder
hey che è bello anche l'uomo non sapevo che avresti potuto invertire il set di caratteri. Mi chiedo come funziona in altre lingue come il cinese –
Mi piace molto il RegexKitLite Framework. Usa la libreria regex dell'ICU, che è già inclusa in OSX ed è sicura da unicode.
NSString *str = @"testString";
[str isMatchedByRegex:@"^[a-zA-Z0-9]*$"]; // strict ASCII-match
[str isMatchedByRegex:@"^[\p{L}\p{N}]*$"]; // unicode letters and numbers match
Le NSCharacterSet
risposte basate non danno i risultati ci si potrebbe aspettare per il testo giapponese, ecc, spesso sostenendo che essi contengono caratteri alfanumerici - la prova viene eseguita riduce a 'ci sono solo lettere o numeri', e I caratteri giapponesi (ecc.) Contano come "lettere". (Es. Giapponese)
Se stai cercando di controllare caratteri latini contro una lingua straniera, allora la risposta da "How to determine if an NSString is latin based?" può aiutare:
BOOL isLatin = [myString canBeConvertedToEncoding:NSISOLatin1StringEncoding];
NSASCIIStringEncoding
potrebbe essere utilizzato anche al posto di NSISOLatin1StringEncoding a ulteriori limitare i caratteri validi. Si potrebbe anche provare utilizzando NSCharacterSet in seguito, per escludere i caratteri speciali come!, #, Ecc
Caratteri speciali come '#', ' @ ', ecc. può anche essere convertito in codifica latina, quindi questo metodo funziona solo per il controllo latin vs. locale specifico. –
- (BOOL)isAlphaNumeric
{
NSCharacterSet *s = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'. "];
s = [s invertedSet];
NSRange r = [self rangeOfCharacterFromSet:s];
if (r.location == NSNotFound) {
return NO;
} else {
return YES;
}
}
ha la flessibilità per aggiungere/togliere nuovi personaggi come spazi bianchi
PS Questo metodo può essere copia/incolla in Categoria NSString
Penso che si possa cambiare l'ultimo pezzo di codice in 'return r.location == NSNotFound;' – agmezr
Ho eseguito alcuni test delle prestazioni piuttosto estesi e ci sono diverse considerazioni da prendere in considerazione quando si sceglie come convalidare le stringhe alfanumeriche. In primo luogo, naturalmente, è che potresti non interessarti alle prestazioni. Se la tua app convalida raramente le stringhe, o forse lo fa anche solo una volta, qualunque metodo ti dia il comportamento che vuoi va bene. Oltre a ciò, ecco i risultati delle mie prestazioni.
per set di caratteri personalizzati (dire caratteri alfanumerici, senza caratteri Unicode o segni), questo è più veloce per una corsa iniziale:
NSCharacterSet *alphanumericSet = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"];
NSString *result = [self stringByTrimmingCharactersInSet:alphanumericSet];
return [result isEqualToString:@""];
Se stai bene utilizzando un carattere precalcolate incastonato come [NSCharacterSet alphanumericCharacterSet]
allora questo è stato più veloce:
NSCharacterSet *alphanumericSet = [NSCharacterSet alphanumericCharacterSet];
alphanumericSet = alphanumericSet.invertedSet;
NSRange range = [self rangeOfCharacterFromSet:alphanumericSet];
return (range.location == NSNotFound);
Caching il set di caratteri in una variabile statica utilizzando dispatch_once
può aiutare un po 'se si esegue più volte queste convalide.In tal caso, se si è sicuri si può assorbire il tempo di compilazione iniziale, utilizzando un'espressione regolare in realtà si rivela essere il più veloce per set di caratteri personalizzati:
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);
Se non si desidera utilizzare l'espressione regolare, la versione set personalizzato della cache rangeOfCharacterFromSet
bordi fuori la cache stringByTrimmingCharactersInCharacterSet:
metodo:
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);
Per i set precalcolate, il rangeOfCharacterFromSet:
metodo di cache è stato di nuovo il più veloce:
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);
E per tutte le informazioni, il metodo isSupersetOfSet:
era il più lento, indipendentemente dalla cache. Sembra che isSupersetOfSet:
sia piuttosto lento.
NSCharacterSet *stringSet = [NSCharacterSet characterSetWithCharactersInString:self];
NSCharacterSet *alphanumericSet = [NSCharacterSet alphanumericCharacterSet];
return [alphanumericSet isSupersetOfSet:stringSet];
non ho fatto alcun test delle funzioni CFCharacterSet sottostanti.
Ottima risposta. Un sacco di piccoli trucchi con [NSCharacterSet alhanumericCharacterSet]. Il semplice e inelegante "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" era esattamente quello di cui avevo bisogno per evitare i caratteri cinesi/giapponesi nel rilevamento alfanumerico. – JeremyDay
È possibile utilizzare le funzionalità NSString
espressioni regolari, introdotte in iOS 3.2:
- (BOOL)isAlphanumeric:(NSString *)string {
return [string rangeOfString:@"^[a-zA-Z0-9]+$" options:NSRegularExpressionSearch].location != NSNotFound;
}
In Swift: http://stackoverflow.com/questions/35992800/check-if-a-string-is-alphanumeric- in-swift – ma11hew28