【问题标题】:TextField Validation With Regular Expression使用正则表达式验证文本字段
【发布时间】:2011-04-23 17:10:21
【问题描述】:

我需要有关查看文本字段的代码的帮助,确保它以 (+ 或 -) 开头,然后有 3 个整数。

所以有效数据看起来像 +234 或 -888

所以我已经启动了这段代码,但它有两个问题

  1. 它正确验证只输入了 4 个字符。但是由于某种原因,您必须将焦点从文本字段上移开,以便键盘上的“完成”按钮触发并隐藏键盘。如果我只在文本字段中输入少于 4 个字符,则完成按钮可以正常工作。但我不希望用户输入除 4 个字符之外的任何内容,然后按完成并隐藏键盘。这是第一个问题....

  2. 我不熟悉正则表达式以及如何在 iphone 中使用它们。所以我需要为上面的要求添加这个代码正则表达式。

    -(BOOL)textField:(UITextField*)textFieldshouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
         NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
         return !([newString length] > 4);
    }
    //Done button to hide the keyboard
    -(IBAction)Done:(id)sender
    {
    
    }
    

【问题讨论】:

    标签: iphone regex cocoa-touch ios4


    【解决方案1】:

    我不确定您希望如何处理用户输入和反馈。首先,我将展示一种简单的方法,让用户在输入无效时保持在 textField 的编辑模式。

    首先是两个委托方法:

    - (BOOL)textFieldShouldReturn:(UITextField *)aTextField
    {
        [aTextField resignFirstResponder];
        return YES;
    }
    
    - (BOOL)textFieldShouldEndEditing:(UITextField *)aTextField
    {
        return [self validateInputWithString:aTextField.text];
    }
    

    测试方法,无论输入是否有效,只返回YES或NO:

    - (BOOL)validateInputWithString:(NSString *)aString
    {
        NSString * const regularExpression = @"^([+-]{1})([0-9]{3})$";
        NSError *error = NULL;
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regularExpression
                                                                               options:NSRegularExpressionCaseInsensitive
                                                                                 error:&error];
        if (error) {
            NSLog(@"error %@", error);
        }
    
        NSUInteger numberOfMatches = [regex numberOfMatchesInString:aString
                                                            options:0
                                                              range:NSMakeRange(0, [aString length])];
        return numberOfMatches > 0;
    }
    

    就是这样。但是,无论他的输入是否正常,我都建议向用户显示一些实时状态。添加以下通知,例如在您的 viewDidLoad 方法中:

    - (void)viewDidLoad
    {
        // ...
        [[NSNotificationCenter defaultCenter] addObserver:self 
                                                 selector:@selector(validateInputCallback:) 
                                                     name:@"UITextFieldTextDidChangeNotification" 
                                                   object:nil];
    }
    
    - (void)validateInputCallback:(id)sender
    {
        if ([self validateInputWithString:textField.text]) {
            // For example turn a label green and let it say: "OK"
        } else {
            // For example turn a label red and let it say: "Allowed: + or minus followed by exactly three digits"
        }
    }
    

    最后:如果您需要访问正则表达式的捕获组(+ 或 - 和数字),以下代码将有所帮助:

    // ... reg ex creation ...
    NSArray *matches = [regex matchesInString:aString
                                      options:0
                                        range:NSMakeRange(0, [aString length])];
    
    for (NSTextCheckingResult *match in matches) {
        for (int i = 0; i < [match numberOfRanges]; i++) {
            NSLog(@"range %d: %d %d", i, [match rangeAtIndex:i].location, [match rangeAtIndex:i].length);
            NSLog(@"substring %d: %@", i, [aString substringWithRange:[match rangeAtIndex:i]]);
        }
    }
    

    【讨论】:

      【解决方案2】:

      使用正则表达式验证电子邮件 ID或电话号码

      Ddelegate 方法:

      - (BOOL)textFieldShouldReturn:(UITextField *)aTextField
      {
          [aTextField resignFirstResponder];
          return YES;
      }
      
      - (BOOL)textFieldShouldEndEditing:(UITextField *)aTextField
      {
          return [self validateEmail:aTextField.text]; // Change validateEmail to validatePhone for phone validation.
      }
      

      无论输入是否有效,都返回 YES 或 NO:

      - (BOOL) validateEmail: (NSString *) candidate {
          NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; 
          NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex]; 
      
          return [emailTest evaluateWithObject:candidate];
      }
      
      - (BOOL) validatePhone: (NSString *) candidate {
          NSString *phoneRegex = @"^+(?:[0-9] ?){6,14}[0-9]$"; 
          NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", phoneRegex]; 
      
          return [phoneTest evaluateWithObject:candidate];
      }
      

      【讨论】:

        【解决方案3】:

        改用 UIPickerView

        我偏离了问题标题,但恕我直言,考虑到您的需要,最好使用 UIPickerView 来拥有“旋转轮”类型的条目,就像您在设置闹钟时在时钟应用程序中所做的那样。它可以从“+000”开始,用户可以根据需要滚动四个轮子([+-]。[0-9],[0-9],[0-9])

        【讨论】:

          【解决方案4】:

          在您的UITextFieldDelegate 中实现-textField:shouldChangeCharactersInRange:replacementString 并使用NSRegularExpression 来验证更改。

          【讨论】:

          • 你能给我看一个代码示例吗?我现在正在玩这个,但在让它正常工作时遇到问题。
          • @Nick,你具体遇到了什么问题?如果您发布您目前所拥有的内容,这可能会有所帮助。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-24
          • 2021-11-28
          • 2021-08-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多