使用正则表达式进行文本字段验证

11

我需要帮助编写代码,检查文本字段是否以+或-开头,并在其后有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
{

}
4个回答

31

我不确定您希望如何处理用户输入和反馈。首先,我将展示一种简单的方法来保持用户在编辑模式下的文本字段中,如果其输入无效。

首先是两个委托方法:

- (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]]);
    }
}

10

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

委托方法:

- (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])。


0

你能给我展示一段代码示例吗?我现在正在尝试但是遇到了无法正常运行的问题。 - Nick LaMarca
@Nick,你具体遇到了什么问题?如果你能发布一下你目前的代码,可能会更有帮助。 - conmulligan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接