2009-11-04 39 views

Odpowiedz

83

Jeśli nie chcesz wnieść w regex biblioteki dla tego jednego zadania ...

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

thz alot dude myślałem coś o tej samej linii co ty, ale po prostu nie mogłem zrozumieć, jak to jest –

+4

Sprawdza tylko znaki na obu końcach łańcucha, a nie cały ciąg – ragamufin

+0

nie działa dla mnie – NightFury

9

Możesz użyć this regular expression library dla ObjectiveC. Użyj następującego wyrażenia regularnego, aby dopasować:

^[a-zA-Z0-9]*$ 
+2

Nie jest źle, ale naprawdę przesada. – Chuck

+1

Dlaczego to przesada? Jest to najprostsze rozwiązanie, łatwe do odczytania i sprawdzania ciągów znaków, do czego przeznaczony był regex. – Soviut

60

to będzie działać:

@implementation NSString (alphaOnly) 

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

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

@end 
+11

'? TAK: NIE "nie jest naprawdę konieczne. Wynik porównania logicznego jest już wartością logiczną. – Chuck

+1

Wiem, po prostu lubię to widzieć, więc nie czytam tego później i myślę, że coś zostawiłem. – NSResponder

+0

Hej, to miłe, zbyt człowiek, nie wiedziałem, że możesz odwrócić zestaw znaków. Zastanawiam się, jak to działa dla innych języków, takich jak chiński –

2

Bardzo podoba mi się szkielet RegexKitLite. Używa biblioteki regex ICU, która jest już dołączona do OSX i jest bezpieczna dla 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

NSCharacterSet odpowiedzi opartej na nie dają rezultatów można się spodziewać tekstu japońskiego itp, często twierdząc, że robią zawierać znaki alfanumeryczne - badanie jest wykonywane sprowadza się do „tam są tylko litery lub cyfry” i Japońskie znaki (itp.) Liczą się jako "Listy". (Np. Japoński)

Jeśli starasz się, by sprawdzić znaki łacińskie vs języku obcym, to odpowiedź od „How to determine if an NSString is latin based?” może pomóc:

BOOL isLatin = [myString canBeConvertedToEncoding:NSISOLatin1StringEncoding]; 

NSASCIIStringEncoding może być również stosowany zamiast NSISOLatin1StringEncoding dalszego ogranicz ważne znaki. Można również sprawdzić za pomocą NSCharacterSet potem wykluczyć znaki specjalne jak!, #, itp

+0

Znaki specjalne, takie jak "#", " @ ', itp. można również konwertować na kodowanie łacińskie, więc ta metoda działa tylko w przypadku łacińskiego vs. –

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

ma możliwość dodawania/odejmij nowe postacie jak whitespaces

PS Ta metoda może być kopiuj/wklej w NSString kategoria

+3

Myślę, że możesz zmienić ostatni fragment kodu na 'return r.location == NSNotFound;' – agmezr

5

Przeprowadziłem dość obszerne testy wydajności i należy wziąć pod uwagę kilka kwestii przy wyborze sposobu sprawdzania łańcuchów alfanumerycznych. Po pierwsze, oczywiście nie musisz przejmować się wydajnością. Jeśli twoja aplikacja rzadko sprawdza poprawność łańcuchów, a może robi to tylko raz, to jakakolwiek metoda, która daje ci pożądane zachowanie, jest w porządku. Poza tym, oto moje wyniki wydajności.

Dla własnych zestawów znaków (słownie znaków alfanumerycznych, bez znaków Unicode lub znaków), jest to najszybszy na początkowy biegu:

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

return [result isEqualToString:@""]; 

Jeśli jesteś w porządku przy użyciu zestawu znaków precomputed jak [NSCharacterSet alphanumericCharacterSet] wtedy to było najszybciej:

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

return (range.location == NSNotFound); 

Buforowanie zestaw znaków w zmiennej statycznej przy użyciu dispatch_once może pomóc trochę jeśli uruchomić te walidacji wielokrotnie.W takim przypadku, jeśli jesteś pewien, można wchłonąć początkowy czas kompilacji przy użyciu regex w rzeczywistości okazuje się być najszybszy na niestandardowe zestawy znaków:

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

Jeśli nie chcesz korzystać z regex, zwyczaj zestaw wersję pamięci podręcznej rangeOfCharacterFromSet krawędzie się w pamięci podręcznej stringByTrimmingCharactersInCharacterSet: metody:

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

Dla precomputed zestawach pamięci podręcznej rangeOfCharacterFromSet: metoda była ponownie najszybszy:

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

I dla wszystkich informacji, metoda isSupersetOfSet: była najwolniejsza, zarówno buforowana, jak i nie. Wygląda na to, że isSupersetOfSet: jest dość powolny.

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

return [alphanumericSet isSupersetOfSet:stringSet]; 

Nie wykonałem żadnych testów podstawowych funkcji CFCharacterSet.

+0

Świetna odpowiedź. Wiele małych seriali z [NSCharacterSet alfanumericCharacterSet]. Proste i nieeleganckie "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" było dokładnie tym, czego potrzebowałem, aby uniknąć chińskich/japońskich znaków w wykryciu alfanumerycznym. – JeremyDay

0

Można użyć NSString regularne możliwości ekspresyjnych, wprowadzone w iOS 3.2:

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