1

What's the best way to make sure an NSString contains only the letters a-z and A-Z.

I've tried the following code but it's not working for some reason:

NSString *myegex = @"[A-Za-z]";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", myregex];
if (![emailTest evaluateWithObject:self.initials.text])  {
     // print error
     return;
}
nhgrif
  • 61,578
  • 25
  • 134
  • 173
Apollo
  • 8,874
  • 32
  • 104
  • 192
  • 2
    What does "it's not working for some reason" mean? Is it failing to compile? Is it throwing a run-time exception? Is there a compile-time error? Is it producing unintended results (what are the results for what input and how does this compare to intended results)? Is it launching missiles? What's happening? – nhgrif Jun 07 '15 at 23:44

2 Answers2

14

You can do it in a simpler way by creating your own NSCharacterSet then checking the string against that set with rangeOfCharacterFromSet:

//Create character set
NSCharacterSet *validChars = [NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"];

//Invert the set
validChars = [validChars invertedSet];

//Check against that
NSRange  range = [myString rangeOfCharacterFromSet:validChars];
if (NSNotFound != range.location) {

 //invalid chars found

}
Michael
  • 6,561
  • 5
  • 38
  • 55
  • 2
    Nice, but I'd use [`+[NSCharacterSet letterCharacterSet]`](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSCharacterSet_Class/index.html#//apple_ref/occ/clm/NSCharacterSet/letterCharacterSet) instead of hard-coding all the letters. – zpasternack Jun 07 '15 at 23:45
  • @zpasternack Well, I saw his string named `emailTest` and figured he is trying to validate an email address that can obviously contain more that only letters. It is basically a hack to avoid complicated regex, although in this case the OP may need exactly that. – Michael Jun 07 '15 at 23:48
  • @zpasternack letterCharacterSet DOES include the period punctuation and other marks. =( https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSCharacterSet_Class/#//apple_ref/occ/clm/NSCharacterSet/letterCharacterSet – jungledev Jan 16 '16 at 23:26
  • @jungledev Doesn't include period or punctuation; includes Marks, which [the docs](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSCharacterSet_Class/index.html#//apple_ref/occ/clm/NSCharacterSet/nonBaseCharacterSet) define as "...all legal Unicode characters with a non-spacing priority greater than 0. Informally, this set is the set of all characters used as modifiers of base characters." – zpasternack Jan 18 '16 at 01:01
  • @zpasternack, I understand what is explained in the docs (which I referred to in order to figure out that it doesn't exclude periods), but in actual use, periods are NOT excluded, so be warned. Perhaps it's an Obj-C bug? I don't know. I was working on the CodeEval "Roller Coaster" algorithm challenge (https://www.codeeval.com/open_challenges/156/), and spent a long time debugging why my solution didn't work. It didn't work because letterCharacterSet doesn't exclude periods. – jungledev Jan 19 '16 at 00:43
0

I'm not sure how Objective-C regex engine works, but you can leverage anchors ^ and $ to check if your string starts and finishes with letters by using this regex:

^[A-Za-z]+$

Using your code, would be:

NSString *myegex = @"^[A-Za-z]+$";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", myregex];
if (![emailTest evaluateWithObject:self.initials.text])  {
     // print error
     return;
}
Federico Piazza
  • 30,085
  • 15
  • 87
  • 123