views:

577

answers:

2

What's wrong with the following code?

-(IBAction)numFieldDoneEditing{
        NSPredicate * regexTest = [NSPredicate predicateWithFormat: @"SELF MATCHES '^\\d*\\.\\d{2}$'"];
        NSString *text = [[NSString alloc] initWithFormat: @"%@", numberField.text];
        if ([regexTest evaluateWithObject: text] == YES) {
          //do something
        }
        else{
          //do something else
        }
        [text release];
        [regexTest release];
    }
+3  A: 

For some reason, you have to escape your backslashes twice for the \d sequence in the regex specification:

NSPredicate * regexTest = [NSPredicate predicateWithFormat: @"SELF MATCHES '^\\\\d*\\.\\\\d{2}$'"];

Some other problems with your code:

  • You shouldn't be releasing the regexText object because you're not an owner. It wasn't created with a method named init or copy. See the Memory Management Programming Guide for Cocoa
  • This is more of a style issue, but if you have a boolean variable, don't compare it for equality with YES or NO, it just makes the code harder to understand. Just test it or its inverse directly. For example:

    // Positive test:
    if([regexTest evaluateWithObject: text])
        ; // do stuff
    
    
    // Negative test
    if(![regexTest evaluateWithObject: text])
        ; // do stuff
    
Adam Rosenfield
About BOOLs: It's more than a style thing. There's no guarantee that a BOOL will only be set to YES or NO. Since BOOL is the same thing as a char, it's entirely possible to say BOOL flag = 42. It's bad style, but it does happen, so your code shouldn't ever test against YES.
Chuck
Can we replace "for some reason..." with an actual reason?
Outlaw Programmer
So, 42 would mean NO?
Ferruccio
+2  A: 

Since you tagged this with iphone and cocoa-touch, it should be worth noting that NSPredicate is not available on the iPhone. It will still work in the simulator, since that uses the desktop frameworks, but it won't work on the iPhone itself.

Martin Gordon