iOS正则表达式

时间:2014-11-25 07:00:15

标签: ios objective-c regex

我正在尝试针对以下正则表达式验证字符串:

[(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}]
  1. 如果使用numberOfMatches方法完成验证,则验证通过,如下所示:

    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@“[(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}]” options:0 error:&error];
    NSUInteger numberOfMatches = [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, string.length)];
    
    BOOL status numberOfMatches == string.length;
    
  2. 如果使用NSPredicate进行验证,则验证失败:

    NSPredicate *test = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", [(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}]];
    BOOL status  = [test evaluateWithObject:string];
    
  3. 这是什么原因?我想用NSPredicate来做这件事。

1 个答案:

答案 0 :(得分:1)

使用[]围绕正则表达式是错误的,因为内部的所有内容都被解释为字符类的一部分。在你的情况下:

[(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}]

这是一个包含A-Z0-9a-z{}()?=.,*的字符类。

由于NSRegularExpression正在使用ICU的正则表达式库,因此它支持字符类联合,就像在Java中一样。

正确的正则表达式应该是:

^(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}$

NSRegularExpression的第一段代码应为:

NSRegularExpression *regex = [NSRegularExpression
                                 regularExpressionWithPattern:
                                     @"^(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}$"
                                 options:0
                                 error:&error];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string
                                    options:0
                                    range:NSMakeRange(0, string.length)];

BOOL status = numberOfMatches == 1;

由于正则表达式仅在匹配整个字符串时匹配,因此最多可获得1个匹配。

NSPredicate的第二段代码应为:

NSPredicate *test = [NSPredicate predicateWithFormat:
                            @"SELF MATCHES %@",
                            @"'^(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}$'"];
BOOL status = [test evaluateWithObject:string];

请注意,除了必须为String对象文字转义\之外,还需要take care of another level of escaping for the string literal in predicate syntax(参见示例)。幸运的是,我们不必在此处理这一点,因为你没有在你的正则表达式中使用\

不应该直接在格式字符串中指定正则表达式(就像在前一版本中一样),因为它将导致格式字符串语法的另一级转义。