我正在尝试针对以下正则表达式验证字符串:
[(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}]
如果使用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;
如果使用NSPredicate
进行验证,则验证失败:
NSPredicate *test = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", [(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}]];
BOOL status = [test evaluateWithObject:string];
这是什么原因?我想用NSPredicate
来做这件事。
答案 0 :(得分:1)
使用[]
围绕正则表达式是错误的,因为内部的所有内容都被解释为字符类的一部分。在你的情况下:
[(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}]
这是一个包含A-Z
,0-9
,a-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(参见示例)。幸运的是,我们不必在此处理这一点,因为你没有在你的正则表达式中使用\
。
不应该直接在格式字符串中指定正则表达式(就像在前一版本中一样),因为它将导致格式字符串语法的另一级转义。